Snap for 4662252 from 2d8bca0b7f655363cdfa31141621e43777d42c49 to pi-release
Change-Id: I0f59941ffbfe380cb5a5e340e013f11fdb00b333
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 2200c4b..c184044 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,12 +1,82 @@
{
"version": "0.2.0",
"configurations": [
-
+ {
+ "name": "Gnome",
+ "type": "cppdbg",
+ "request": "launch",
+ "preLaunchTask": "make",
+ "program": "${workspaceRoot}/debug/OGLESIntroducingPVRApi",
+ "args": ["LD_LIBRARY_PATH=./"],
+ "stopAtEntry": false,
+ "cwd": "${workspaceRoot}/debug/",
+ "environment": [],
+ "externalConsole": true,
+ "linux": {
+ "MIMode": "gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ }
+ ]
+ },
+ "osx": {
+ "MIMode": "lldb"
+ },
+ "windows": {
+ "MIMode": "gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "Glass",
+ "type": "cppdbg",
+ "request": "launch",
+ "preLaunchTask": "make",
+ "program": "${workspaceRoot}/debug/OGLESGlass",
+ "args": ["LD_LIBRARY_PATH=./"],
+ "stopAtEntry": false,
+ "cwd": "${workspaceRoot}/debug/",
+ "environment": [],
+ "externalConsole": true,
+ "linux": {
+ "MIMode": "gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ }
+ ]
+ },
+ "osx": {
+ "MIMode": "lldb"
+ },
+ "windows": {
+ "MIMode": "gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ }
+ ]
+ }
+ },
{
"name": "SubzeroTest",
"type": "cppdbg",
"request": "launch",
- "program": "${workspaceRoot}/build/SubzeroTest",
+ "preLaunchTask": "make",
+ "program": "${workspaceRoot}/debug/SubzeroTest",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
@@ -40,7 +110,8 @@
"name": "OGLES2HelloAPI",
"type": "cppdbg",
"request": "launch",
- "program": "${workspaceRoot}/build/OGLES2HelloAPI",
+ "preLaunchTask": "make",
+ "program": "${workspaceRoot}/debug/OGLES2HelloAPI",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 71f226d..2c00e06 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -17,7 +17,7 @@
"showOutput": "always",
"suppressTaskName": true,
"options": {
- "cwd": "${workspaceRoot}/build"
+ "cwd": "${workspaceRoot}/debug"
},
"tasks": [
{
diff --git a/BUILD.gn b/BUILD.gn
index 0ef68d9..7af9f6a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import("//build/config/c++/c++.gni")
import("//build/config/compiler/compiler.gni")
config("swiftshader_config") {
@@ -21,11 +22,22 @@
cflags = [
"/GS", # Detects some buffer overruns
"/Zc:wchar_t",
- "/EHsc",
+ "/EHs-c-", # Disable C++ exceptions
"/nologo",
"/Gd", # Default calling convention
]
+ if (!use_custom_libcxx) {
+ # Disable EH usage in STL headers.
+ # libc++ uses a predefined macro to control whether to use exceptions, so
+ # defining this macro is unnecessary. Defining _HAS_EXCEPTIONS to 0 also
+ # breaks libc++ because it depends on MSVC headers that only provide
+ # certain declarations if _HAS_EXCEPTIONS is 1.
+ defines += [
+ "_HAS_EXCEPTIONS=0",
+ ]
+ }
+
defines += [
"_CRT_SECURE_NO_DEPRECATE",
"NOMINMAX",
@@ -73,13 +85,16 @@
cflags += [
"-m64",
"-fPIC",
- "-march=core2",
+ "-march=x86-64",
+ "-mtune=generic",
]
} else { # 32 bit version
cflags += [
"-m32",
"-msse2",
- "-march=i686",
+ "-mfpmath=sse",
+ "-march=pentium4",
+ "-mtune=generic",
]
}
@@ -97,6 +112,25 @@
}
}
+source_set("vertex_routine_fuzzer") {
+ sources = [
+ "tests/fuzzers/VertexRoutineFuzzer.cpp"
+ ]
+ if (is_win) {
+ cflags = [
+ "/wd4201", # nameless struct/union
+ "/wd4065", # switch statement contains 'default' but no 'case' labels
+ "/wd5030", # attribute is not recognized
+ ]
+ }
+ include_dirs = [
+ "src/",
+ ]
+ deps = [
+ "src/OpenGL/libGLESv2:swiftshader_libGLESv2_static",
+ ]
+}
+
group("swiftshader") {
data_deps = [
"src/OpenGL/libGLESv2:swiftshader_libGLESv2",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 619111f..834d4c1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -110,7 +110,8 @@
# hides all the others. Gc sections is used in combination
# with each functions being in its section, to reduce the
# binary size.
- set_target_properties(${TARGET} PROPERTIES LINK_FLAGS "${LINKFLAGS} -Wl,--hash-style=both,--version-script=${DIR}/exports.map,--gc-sections,--no-undefined")
+ set_target_properties(${TARGET} PROPERTIES LINK_FLAGS "${LINKFLAGS} -Wl,--hash-style=both,--version-script=${DIR}/${TARGET}.lds,--gc-sections,--no-undefined")
+ set_target_properties(${TARGET} PROPERTIES LINK_DEPENDS "${DIR}/${TARGET}.lds")
endif()
endmacro()
@@ -149,6 +150,8 @@
else()
set_cpp_flag("--std=c++11")
set_cpp_flag("-Wall")
+ set_cpp_flag("-Werror=reorder")
+ set_cpp_flag("-Werror=sign-compare")
set_cpp_flag("-fno-exceptions")
# Don't allow symbols to be overridden by another module.
@@ -165,12 +168,15 @@
if(ARCH EQUAL "x86")
set_cpp_flag("-m32")
set_cpp_flag("-msse2")
- set_cpp_flag("-march=i686")
+ set_cpp_flag("-mfpmath=sse")
+ set_cpp_flag("-march=pentium4")
+ set_cpp_flag("-mtune=generic")
endif()
if(ARCH EQUAL "x86_64")
set_cpp_flag("-m64")
set_cpp_flag("-fPIC")
- set_cpp_flag("-march=core2")
+ set_cpp_flag("-march=x86-64")
+ set_cpp_flag("-mtune=generic")
endif()
# Use -g3 to have even more debug info
@@ -687,11 +693,6 @@
set(COMMON_INCLUDE_DIR
${SOURCE_DIR}
- ${SOURCE_DIR}/Common
- ${SOURCE_DIR}/Main
- ${SOURCE_DIR}/Reactor
- ${SOURCE_DIR}/Renderer
- ${SOURCE_DIR}/Shader
${CMAKE_SOURCE_DIR}/include
${LLVM_INCLUDE_DIR}
)
diff --git a/OWNERS b/OWNERS
index 7aa5e42..a402880 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,4 +4,6 @@
# in this list has approved a SwiftShader related change before landing it.
nicolascapens@google.com
-sugoi@google.com
\ No newline at end of file
+sugoi@google.com
+
+# COMPONENT: Internals>GPU>SwiftShader
\ No newline at end of file
diff --git a/SwiftShader.sln b/SwiftShader.sln
index d0501a3..c216b78 100644
--- a/SwiftShader.sln
+++ b/SwiftShader.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.16
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LLVM", "LLVM", "{B408B98A-E888-4ECF-81E0-7A37A6854B17}"
EndProject
@@ -826,4 +826,7 @@
{4EC107AB-89E8-4A0B-8366-B3E81085AE07} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}
{CF8EBC89-8762-49DC-9440-6C82B3499913} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4DF423D2-8425-48A7-9CEC-835C4C3CA957}
+ EndGlobalSection
EndGlobal
diff --git a/docs/Index.md b/docs/Index.md
index 12c4318..f51f87e 100644
--- a/docs/Index.md
+++ b/docs/Index.md
@@ -55,7 +55,7 @@
The GLSL compiler is implemented in [src/OpenGL/compiler/](../src/OpenGL/compiler/). It uses [Flex](http://flex.sourceforge.net/) and [Bison](https://www.gnu.org/software/bison/) to tokenize and parse GLSL shader source. It produces an [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST), which is then traversed to output assembly-level instructions in [OutputASM.cpp](../src/OpenGL/compiler/OutputASM.cpp).
-The [EGL](https://www.khronos.org/registry/egl/specs/eglspec.1.4.20110406.pdf) API is implemented in [src/OpenGL/libEGL/](../src/OpenGL/libEGL/). Its entry functions are listed in [libEGL.def](../src/OpenGL/libEGL/libEGL.def) (for Windows) and [exports.map](../src/OpenGL/libEGL/exports.map) (for Linux), and defined in [main.cpp](../src/OpenGL/libEGL/main.cpp) and implemented in [libEGL.cpp](../src/OpenGL/libEGL/libEGL.cpp). The [Display](../src/OpenGL/libEGL/Display.h), [Surface](../src/OpenGL/libEGL/Surface.h), and [Config](../src/OpenGL/libEGL/Config.h) classes are respective implementations of the abstract EGLDisplay, EGLSurface, and EGLConfig types.
+The [EGL](https://www.khronos.org/registry/egl/specs/eglspec.1.4.20110406.pdf) API is implemented in [src/OpenGL/libEGL/](../src/OpenGL/libEGL/). Its entry functions are listed in [libEGL.def](../src/OpenGL/libEGL/libEGL.def) (for Windows) and [libEGL.lds](../src/OpenGL/libEGL/libEGL.lds) (for Linux), and defined in [main.cpp](../src/OpenGL/libEGL/main.cpp) and implemented in [libEGL.cpp](../src/OpenGL/libEGL/libEGL.cpp). The [Display](../src/OpenGL/libEGL/Display.h), [Surface](../src/OpenGL/libEGL/Surface.h), and [Config](../src/OpenGL/libEGL/Config.h) classes are respective implementations of the abstract EGLDisplay, EGLSurface, and EGLConfig types.
[OpenGL ES 1.1](https://www.khronos.org/registry/gles/specs/1.1/es_full_spec_1.1.12.pdf) is implemented in [src/OpenGL/libGLES_CM/](../src/OpenGL/libGLES_CM/), while [OpenGL ES 2.0](https://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf) is implemented in [src/OpenGL/libGLESv2/](../src/OpenGL/libGLESv2/). Note that while [OpenGL ES 3.0](https://www.khronos.org/registry/gles/specs/3.0/es_spec_3.0.0.pdf) functions are implemented in [libGLESv3.cpp](../src/OpenGL/libGLESv2/libGLESv3.cpp), it is compiled into the libGLESv2 library as standard among most implementations (some platforms have a libGLESv3 symbolically link to libGLESv2). We'll focus on OpenGL ES 2.0 in this documentation.
diff --git a/src/Android.mk b/src/Android.mk
index dc31261..945daf8 100644
--- a/src/Android.mk
+++ b/src/Android.mk
@@ -4,11 +4,7 @@
bionic \
$(LOCAL_PATH)/../include \
$(LOCAL_PATH)/OpenGL/ \
- $(LOCAL_PATH) \
- $(LOCAL_PATH)/Renderer/ \
- $(LOCAL_PATH)/Common/ \
- $(LOCAL_PATH)/Shader/ \
- $(LOCAL_PATH)/Main/
+ $(LOCAL_PATH)
ifdef use_subzero
COMMON_C_INCLUDES += \
diff --git a/src/Common/Debug.hpp b/src/Common/Debug.hpp
index 0632743..5ccc35a 100644
--- a/src/Common/Debug.hpp
+++ b/src/Common/Debug.hpp
@@ -27,19 +27,19 @@
void trace(const char *format, ...);
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define TRACE(format, ...) trace("[0x%0.8X]%s(" format ")\n", this, __FUNCTION__, ##__VA_ARGS__)
#else
#define TRACE(...) ((void)0)
#endif
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define UNIMPLEMENTED() {trace("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); ASSERT(false);}
#else
#define UNIMPLEMENTED() ((void)0)
#endif
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define ASSERT(expression) {if(!(expression)) trace("\t! Assert failed in %s(%d): " #expression "\n", __FUNCTION__, __LINE__); assert(expression);}
#else
#define ASSERT assert
diff --git a/src/Common/Half.hpp b/src/Common/Half.hpp
index f62ea27..f2d378e 100644
--- a/src/Common/Half.hpp
+++ b/src/Common/Half.hpp
@@ -20,6 +20,7 @@
class half
{
public:
+ half() = default;
explicit half(float f);
operator float() const;
@@ -30,6 +31,63 @@
private:
unsigned short fp16i;
};
+
+ inline half shortAsHalf(short s)
+ {
+ union
+ {
+ half h;
+ short s;
+ } hs;
+
+ hs.s = s;
+
+ return hs.h;
+ }
+
+ class RGB9E5
+ {
+ unsigned int R : 9;
+ unsigned int G : 9;
+ unsigned int B : 9;
+ unsigned int E : 5;
+
+ public:
+ void toRGB16F(half rgb[3]) const
+ {
+ constexpr int offset = 24; // Exponent bias (15) + number of mantissa bits per component (9) = 24
+
+ const float factor = (1u << E) * (1.0f / (1 << offset));
+ rgb[0] = half(R * factor);
+ rgb[1] = half(G * factor);
+ rgb[2] = half(B * factor);
+ }
+ };
+
+ class R11G11B10F
+ {
+ unsigned int R : 11;
+ unsigned int G : 11;
+ unsigned int B : 10;
+
+ static inline half float11ToFloat16(unsigned short fp11)
+ {
+ return shortAsHalf(fp11 << 4); // Sign bit 0
+ }
+
+ static inline half float10ToFloat16(unsigned short fp10)
+ {
+ return shortAsHalf(fp10 << 5); // Sign bit 0
+ }
+
+ public:
+ void toRGB16F(half rgb[3]) const
+ {
+ rgb[0] = float11ToFloat16(R);
+ rgb[1] = float11ToFloat16(G);
+ rgb[2] = float10ToFloat16(B);
+ }
+ };
}
#endif // sw_Half_hpp
diff --git a/src/Common/Math.hpp b/src/Common/Math.hpp
index 0b4abe6..dd2bc9c 100644
--- a/src/Common/Math.hpp
+++ b/src/Common/Math.hpp
@@ -16,6 +16,7 @@
#define sw_Math_hpp
#include "Types.hpp"
+#include "Half.hpp"
#include <cmath>
#if defined(_MSC_VER)
@@ -73,6 +74,18 @@
b = t;
}
+ template <typename destType, typename sourceType>
+ destType bitCast(const sourceType &source)
+ {
+ union
+ {
+ sourceType s;
+ destType d;
+ } sd;
+ sd.s = source;
+ return sd.d;
+ }
+
inline int iround(float x)
{
return (int)floor(x + 0.5f);
@@ -295,6 +308,7 @@
static const unsigned int min = 0x80000000 >> (32 - n);
static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
static const float maxf = static_cast<float>(max);
+ static const float minf = static_cast<float>(min);
static const unsigned int range = 0xFFFFFFFF >> (32 - n);
if(x > 0.0f)
@@ -305,18 +319,18 @@
}
else
{
- return static_cast<int>(maxf * x + 0.5f);
+ return static_cast<int>(x + 0.5f);
}
}
else
{
- if(x <= -1.0f)
+ if(x <= -minf)
{
return min;
}
else
{
- return static_cast<int>(maxf * x - 0.5f) & range;
+ return static_cast<int>(x - 0.5f) & range;
}
}
}
@@ -359,122 +373,6 @@
{
return static_cast<int>(min(x, 0x7FFFFFFFu));
}
-
- class RGB9E5Data
- {
- unsigned int R : 9;
- unsigned int G : 9;
- unsigned int B : 9;
- unsigned int E : 5;
-
- public:
- void toRGBFloats(float* rgb) const
- {
- static const float Offset = -24.0f; // Exponent Bias (15) + Number of mantissa bits per component (9) = 24
-
- const float factor = powf(2.0f, static_cast<float>(E) + Offset);
- rgb[0] = static_cast<float>(R) * factor;
- rgb[1] = static_cast<float>(G) * factor;
- rgb[2] = static_cast<float>(B) * factor;
- }
- };
-
- class R11G11B10FData
- {
- unsigned int R : 11;
- unsigned int G : 11;
- unsigned int B : 10;
-
- static inline float float11ToFloat32(unsigned short fp11)
- {
- unsigned short exponent = (fp11 >> 6) & 0x1F;
- unsigned short mantissa = fp11 & 0x3F;
-
- unsigned int output;
- if(exponent == 0x1F)
- {
- // INF or NAN
- output = 0x7f800000 | (mantissa << 17);
- }
- else
- {
- if(exponent != 0)
- {
- // normalized
- }
- else if(mantissa != 0)
- {
- // The value is denormalized
- exponent = 1;
-
- do
- {
- exponent--;
- mantissa <<= 1;
- } while((mantissa & 0x40) == 0);
-
- mantissa = mantissa & 0x3F;
- }
- else // The value is zero
- {
- exponent = static_cast<unsigned short>(-112);
- }
-
- output = ((exponent + 112) << 23) | (mantissa << 17);
- }
-
- return *(float*)(&output);
- }
-
- static inline float float10ToFloat32(unsigned short fp10)
- {
- unsigned short exponent = (fp10 >> 5) & 0x1F;
- unsigned short mantissa = fp10 & 0x1F;
-
- unsigned int output;
- if(exponent == 0x1F)
- {
- // INF or NAN
- output = 0x7f800000 | (mantissa << 17);
- }
- else
- {
- if(exponent != 0)
- {
- // normalized
- }
- else if(mantissa != 0)
- {
- // The value is denormalized
- exponent = 1;
-
- do
- {
- exponent--;
- mantissa <<= 1;
- } while((mantissa & 0x20) == 0);
-
- mantissa = mantissa & 0x1F;
- }
- else // The value is zero
- {
- exponent = static_cast<unsigned short>(-112);
- }
-
- output = ((exponent + 112) << 23) | (mantissa << 18);
- }
-
- return *(float*)(&output);
- }
-
- public:
- void toRGBFloats(float* rgb) const
- {
- rgb[0] = float11ToFloat32(R);
- rgb[1] = float11ToFloat32(G);
- rgb[2] = float10ToFloat32(B);
- }
- };
}
#endif // sw_Math_hpp
diff --git a/src/Common/MutexLock.hpp b/src/Common/MutexLock.hpp
index 65b4d7e..3a071c9 100644
--- a/src/Common/MutexLock.hpp
+++ b/src/Common/MutexLock.hpp
@@ -57,7 +57,7 @@
};
}
-#else // !__ANDROID__
+#else // !__linux__
#include <atomic>
diff --git a/src/Common/Resource.cpp b/src/Common/Resource.cpp
index e16968a..0e71e05 100644
--- a/src/Common/Resource.cpp
+++ b/src/Common/Resource.cpp
@@ -38,7 +38,7 @@
{
criticalSection.lock();
- while(count != 0 && accessor != claimer)
+ while(count > 0 && accessor != claimer)
{
blocked++;
criticalSection.unlock();
@@ -84,7 +84,7 @@
}
// Acquire
- while(count != 0 && accessor != claimer)
+ while(count > 0 && accessor != claimer)
{
blocked++;
criticalSection.unlock();
diff --git a/src/Common/Socket.cpp b/src/Common/Socket.cpp
index a19f574..b098031 100644
--- a/src/Common/Socket.cpp
+++ b/src/Common/Socket.cpp
@@ -20,6 +20,7 @@
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
+ #include <sys/select.h>
#endif
namespace sw
diff --git a/src/Common/Thread.hpp b/src/Common/Thread.hpp
index 3b9e674..186d1bd 100644
--- a/src/Common/Thread.hpp
+++ b/src/Common/Thread.hpp
@@ -28,6 +28,21 @@
#define TLS_OUT_OF_INDEXES (pthread_key_t)(~0)
#endif
+#include <stdlib.h>
+
+#if defined(__clang__)
+#if __has_include(<atomic>) // clang has an explicit check for the availability of atomic
+#define USE_STD_ATOMIC 1
+#endif
+// atomic is available in C++11 or newer, and in Visual Studio 2012 or newer
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1700)) || (__cplusplus >= 201103L)
+#define USE_STD_ATOMIC 1
+#endif
+
+#if USE_STD_ATOMIC
+#include <atomic>
+#endif
+
namespace sw
{
class Event;
@@ -52,8 +67,9 @@
static LocalStorageKey allocateLocalStorageKey();
static void freeLocalStorageKey(LocalStorageKey key);
- static void setLocalStorage(LocalStorageKey key, void *value);
+ static void *allocateLocalStorage(LocalStorageKey key, size_t size);
static void *getLocalStorage(LocalStorageKey key);
+ static void freeLocalStorage(LocalStorageKey key);
private:
struct Entry
@@ -135,7 +151,7 @@
return TlsAlloc();
#else
LocalStorageKey key;
- pthread_key_create(&key, NULL);
+ pthread_key_create(&key, free);
return key;
#endif
}
@@ -149,16 +165,24 @@
#endif
}
- inline void Thread::setLocalStorage(LocalStorageKey key, void *value)
+ inline void *Thread::allocateLocalStorage(LocalStorageKey key, size_t size)
{
+ if(key == TLS_OUT_OF_INDEXES)
+ {
+ return nullptr;
+ }
+
+ freeLocalStorage(key);
+
+ void *storage = malloc(size);
+
#if defined(_WIN32)
- TlsSetValue(key, value);
+ TlsSetValue(key, storage);
#else
- if(key != TLS_OUT_OF_INDEXES) // Avoid undefined behavior.
- {
- pthread_setspecific(key, value);
- }
+ pthread_setspecific(key, storage);
#endif
+
+ return storage;
}
inline void *Thread::getLocalStorage(LocalStorageKey key)
@@ -175,6 +199,17 @@
#endif
}
+ inline void Thread::freeLocalStorage(LocalStorageKey key)
+ {
+ free(getLocalStorage(key));
+
+ #if defined(_WIN32)
+ TlsSetValue(key, nullptr);
+ #else
+ pthread_setspecific(key, nullptr);
+ #endif
+ }
+
inline void Event::signal()
{
#if defined(_WIN32)
@@ -243,7 +278,7 @@
inline int atomicAdd(volatile int* target, int value)
{
- #if defined(_MSC_VER)
+ #if defined(_WIN32)
return InterlockedExchangeAdd((volatile long*)target, value) + value;
#else
return __sync_add_and_fetch(target, value);
@@ -258,6 +293,46 @@
__asm__ __volatile__ ("nop");
#endif
}
+
+ #if USE_STD_ATOMIC
+ class AtomicInt
+ {
+ public:
+ AtomicInt() : ai() {}
+ AtomicInt(int i) : ai(i) {}
+
+ inline operator int() const { return ai.load(std::memory_order_acquire); }
+ inline void operator=(const AtomicInt& i) { ai.store(i.ai.load(std::memory_order_acquire), std::memory_order_release); }
+ inline void operator=(int i) { ai.store(i, std::memory_order_release); }
+ inline void operator--() { ai.fetch_sub(1, std::memory_order_acq_rel); }
+ inline void operator++() { ai.fetch_add(1, std::memory_order_acq_rel); }
+ inline int operator--(int) { return ai.fetch_sub(1, std::memory_order_acq_rel) - 1; }
+ inline int operator++(int) { return ai.fetch_add(1, std::memory_order_acq_rel) + 1; }
+ inline void operator-=(int i) { ai.fetch_sub(i, std::memory_order_acq_rel); }
+ inline void operator+=(int i) { ai.fetch_add(i, std::memory_order_acq_rel); }
+ private:
+ std::atomic<int> ai;
+ };
+ #else
+ class AtomicInt
+ {
+ public:
+ AtomicInt() {}
+ AtomicInt(int i) : vi(i) {}
+
+ inline operator int() const { return vi; } // Note: this isn't a guaranteed atomic operation
+ inline void operator=(const AtomicInt& i) { sw::atomicExchange(&vi, i.vi); }
+ inline void operator=(int i) { sw::atomicExchange(&vi, i); }
+ inline void operator--() { sw::atomicDecrement(&vi); }
+ inline void operator++() { sw::atomicIncrement(&vi); }
+ inline int operator--(int) { return sw::atomicDecrement(&vi); }
+ inline int operator++(int) { return sw::atomicIncrement(&vi); }
+ inline void operator-=(int i) { sw::atomicAdd(&vi, -i); }
+ inline void operator+=(int i) { sw::atomicAdd(&vi, i); }
+ private:
+ volatile int vi;
+ };
+ #endif
}
#endif // sw_Thread_hpp
diff --git a/src/Common/Version.h b/src/Common/Version.h
index d1beda2..1747820 100644
--- a/src/Common/Version.h
+++ b/src/Common/Version.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#define MAJOR_VERSION 3
-#define MINOR_VERSION 3
+#define MAJOR_VERSION 4
+#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 2
diff --git a/src/D3D8/Capabilities.cpp b/src/D3D8/Capabilities.cpp
index dd0ba20..53cd68e 100644
--- a/src/D3D8/Capabilities.cpp
+++ b/src/D3D8/Capabilities.cpp
@@ -55,11 +55,11 @@
bool Capabilities::Surface::A8P8 = false;
bool Capabilities::Surface::G16R16 = true;
bool Capabilities::Surface::A2B10G10R10 = true;
- bool Capabilities::Surface::DXT1 = S3TC_SUPPORT;
- bool Capabilities::Surface::DXT2 = S3TC_SUPPORT;
- bool Capabilities::Surface::DXT3 = S3TC_SUPPORT;
- bool Capabilities::Surface::DXT4 = S3TC_SUPPORT;
- bool Capabilities::Surface::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::Surface::DXT1 = true;
+ bool Capabilities::Surface::DXT2 = true;
+ bool Capabilities::Surface::DXT3 = true;
+ bool Capabilities::Surface::DXT4 = true;
+ bool Capabilities::Surface::DXT5 = true;
bool Capabilities::Surface::V8U8 = true;
bool Capabilities::Surface::L6V5U5 = true;
bool Capabilities::Surface::X8L8V8U8 = true;
@@ -87,11 +87,11 @@
bool Capabilities::Volume::A8P8 = false;
bool Capabilities::Volume::G16R16 = true;
bool Capabilities::Volume::A2B10G10R10 = true;
- bool Capabilities::Volume::DXT1 = S3TC_SUPPORT;
- bool Capabilities::Volume::DXT2 = S3TC_SUPPORT;
- bool Capabilities::Volume::DXT3 = S3TC_SUPPORT;
- bool Capabilities::Volume::DXT4 = S3TC_SUPPORT;
- bool Capabilities::Volume::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::Volume::DXT1 = true;
+ bool Capabilities::Volume::DXT2 = true;
+ bool Capabilities::Volume::DXT3 = true;
+ bool Capabilities::Volume::DXT4 = true;
+ bool Capabilities::Volume::DXT5 = true;
bool Capabilities::Volume::V8U8 = true;
bool Capabilities::Volume::L6V5U5 = true;
bool Capabilities::Volume::X8L8V8U8 = true;
@@ -139,11 +139,11 @@
bool Capabilities::CubeMap::A8P8 = false;
bool Capabilities::CubeMap::G16R16 = true;
bool Capabilities::CubeMap::A2B10G10R10 = true;
- bool Capabilities::CubeMap::DXT1 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::DXT2 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::DXT3 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::DXT4 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::DXT1 = true;
+ bool Capabilities::CubeMap::DXT2 = true;
+ bool Capabilities::CubeMap::DXT3 = true;
+ bool Capabilities::CubeMap::DXT4 = true;
+ bool Capabilities::CubeMap::DXT5 = true;
bool Capabilities::CubeMap::V8U8 = true;
bool Capabilities::CubeMap::L6V5U5 = true;
bool Capabilities::CubeMap::X8L8V8U8 = true;
@@ -171,11 +171,11 @@
bool Capabilities::VolumeTexture::A8P8 = false;
bool Capabilities::VolumeTexture::G16R16 = true;
bool Capabilities::VolumeTexture::A2B10G10R10 = true;
- bool Capabilities::VolumeTexture::DXT1 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::DXT2 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::DXT3 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::DXT4 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::DXT1 = true;
+ bool Capabilities::VolumeTexture::DXT2 = true;
+ bool Capabilities::VolumeTexture::DXT3 = true;
+ bool Capabilities::VolumeTexture::DXT4 = true;
+ bool Capabilities::VolumeTexture::DXT5 = true;
bool Capabilities::VolumeTexture::V8U8 = true;
bool Capabilities::VolumeTexture::L6V5U5 = true;
bool Capabilities::VolumeTexture::X8L8V8U8 = true;
@@ -223,11 +223,11 @@
bool Capabilities::Texture::A8P8 = false;
bool Capabilities::Texture::G16R16 = true;
bool Capabilities::Texture::A2B10G10R10 = true;
- bool Capabilities::Texture::DXT1 = S3TC_SUPPORT;
- bool Capabilities::Texture::DXT2 = S3TC_SUPPORT;
- bool Capabilities::Texture::DXT3 = S3TC_SUPPORT;
- bool Capabilities::Texture::DXT4 = S3TC_SUPPORT;
- bool Capabilities::Texture::DXT5 = S3TC_SUPPORT;
+ bool Capabilities::Texture::DXT1 = true;
+ bool Capabilities::Texture::DXT2 = true;
+ bool Capabilities::Texture::DXT3 = true;
+ bool Capabilities::Texture::DXT4 = true;
+ bool Capabilities::Texture::DXT5 = true;
bool Capabilities::Texture::V8U8 = true;
bool Capabilities::Texture::L6V5U5 = true;
bool Capabilities::Texture::X8L8V8U8 = true;
diff --git a/src/D3D8/D3D8.vcxproj b/src/D3D8/D3D8.vcxproj
index 6f42a4f..2cc027a 100644
--- a/src/D3D8/D3D8.vcxproj
+++ b/src/D3D8/D3D8.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -17,25 +17,26 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{F18D5ABF-CA3A-4B74-BDB2-4A1956C86F18}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -102,8 +103,6 @@
<ModuleDefinitionFile>d3d8.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AssemblyDebug>true</AssemblyDebug>
- <ProgramDatabaseFile>
- </ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile>
<MapExports>true</MapExports>
<SubSystem>Windows</SubSystem>
diff --git a/src/D3D8/Direct3DDevice8.cpp b/src/D3D8/Direct3DDevice8.cpp
index 7f6e769..1130d11 100644
--- a/src/D3D8/Direct3DDevice8.cpp
+++ b/src/D3D8/Direct3DDevice8.cpp
@@ -2149,7 +2149,7 @@
cursorBitmap->LockRect(&lock, 0, 0);
delete cursor;
- cursor = sw::Surface::create(0, desc.Width, desc.Height, 1, sw::FORMAT_A8R8G8B8, false, false);
+ cursor = sw::Surface::create(0, desc.Width, desc.Height, 1, 0, 1, sw::FORMAT_A8R8G8B8, false, false);
void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
memcpy(buffer, lock.pBits, desc.Width * desc.Height * sizeof(unsigned int));
diff --git a/src/D3D8/Direct3DSurface8.cpp b/src/D3D8/Direct3DSurface8.cpp
index 6ad0e6b..f9d1e96 100644
--- a/src/D3D8/Direct3DSurface8.cpp
+++ b/src/D3D8/Direct3DSurface8.cpp
@@ -58,11 +58,12 @@
return 1;
}
- Direct3DSurface8::Direct3DSurface8(Direct3DDevice8 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, bool lockable, unsigned long usage) : Surface(getParentResource(container), width, height, sampleCount(multiSample), translateFormat(format), lockable, (usage & D3DUSAGE_RENDERTARGET) == D3DUSAGE_RENDERTARGET || (usage & D3DUSAGE_DEPTHSTENCIL) == D3DUSAGE_DEPTHSTENCIL), device(device), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), lockable(lockable), usage(usage)
+ Direct3DSurface8::Direct3DSurface8(Direct3DDevice8 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, bool lockable, unsigned long usage)
+ : Surface(getParentResource(container), width, height, 1, 0, sampleCount(multiSample), translateFormat(format), lockable, (usage & D3DUSAGE_RENDERTARGET) == D3DUSAGE_RENDERTARGET || (usage & D3DUSAGE_DEPTHSTENCIL) == D3DUSAGE_DEPTHSTENCIL), device(device), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), lockable(lockable), usage(usage)
{
parentTexture = dynamic_cast<Direct3DBaseTexture8*>(container);
- resource = new Direct3DResource8(device, D3DRTYPE_SURFACE, memoryUsage(width, height, format));
+ resource = new Direct3DResource8(device, D3DRTYPE_SURFACE, memoryUsage(width, height, multiSample, format));
}
Direct3DSurface8::~Direct3DSurface8()
@@ -227,7 +228,7 @@
desc->Type = D3DRTYPE_SURFACE;
desc->Height = height;
desc->Width = width;
- desc->Size = size(getWidth(), getHeight(), getDepth(), getExternalFormat());
+ desc->Size = memoryUsage(width, height, multiSample, format);
desc->MultiSampleType = multiSample;
desc->Usage = usage;
@@ -283,8 +284,8 @@
return Surface::bytes(translateFormat(format));
}
- unsigned int Direct3DSurface8::memoryUsage(int width, int height, D3DFORMAT format)
+ unsigned int Direct3DSurface8::memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, D3DFORMAT format)
{
- return Surface::size(width, height, 1, translateFormat(format));
+ return Surface::size(width, height, 1, 0, sampleCount(multiSample), translateFormat(format));
}
}
diff --git a/src/D3D8/Direct3DSurface8.hpp b/src/D3D8/Direct3DSurface8.hpp
index e07829d..5ccecf3 100644
--- a/src/D3D8/Direct3DSurface8.hpp
+++ b/src/D3D8/Direct3DSurface8.hpp
@@ -57,7 +57,7 @@
static int bytes(D3DFORMAT format);
private:
- static unsigned int memoryUsage(int width, int height, D3DFORMAT format); // FIXME: Surface::size
+ static unsigned int memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, D3DFORMAT format); // FIXME: Surface::size
// Creation parameters
Direct3DDevice8 *const device;
diff --git a/src/D3D8/Direct3DSwapChain8.cpp b/src/D3D8/Direct3DSwapChain8.cpp
index a49bf11..d0e3b97 100644
--- a/src/D3D8/Direct3DSwapChain8.cpp
+++ b/src/D3D8/Direct3DSwapChain8.cpp
@@ -81,13 +81,9 @@
profiler.nextFrame();
#endif
- void *source = backBuffer[0]->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC); // FIXME: External
- sw::Format format = backBuffer[0]->getInternalFormat();
- int stride = backBuffer[0]->getInternalPitchB();
-
if(!sourceRect && !destRect) // FIXME: More cases?
{
- frameBuffer->flip(destWindowOverride, source, format, stride);
+ frameBuffer->flip(destWindowOverride, backBuffer[0]);
}
else // TODO: Check for SWAPEFFECT_COPY
{
@@ -110,11 +106,9 @@
dRect.y1 = destRect->bottom;
}
- frameBuffer->blit(destWindowOverride, source, sourceRect ? &sRect : nullptr, destRect ? &dRect : nullptr, format, stride);
+ frameBuffer->blit(destWindowOverride, backBuffer[0], sourceRect ? &sRect : nullptr, destRect ? &dRect : nullptr);
}
- backBuffer[0]->unlockInternal(); // FIXME: External
-
return D3D_OK;
}
@@ -133,7 +127,7 @@
}
this->backBuffer[index]->AddRef();
- *backBuffer = this->backBuffer[index];
+ *backBuffer = this->backBuffer[index];
return D3D_OK;
}
@@ -155,7 +149,7 @@
device->GetCreationParameters(&creationParameters);
HWND windowHandle = presentParameters->hDeviceWindow ? presentParameters->hDeviceWindow : creationParameters.hFocusWindow;
-
+
int width = 0;
int height = 0;
@@ -222,7 +216,7 @@
{
return backBuffer[index]->lockInternal(0, 0, 0, sw::LOCK_READWRITE, sw::PUBLIC); // FIXME: External
}
-
+
void Direct3DSwapChain8::unlockBackBuffer(int index)
{
backBuffer[index]->unlockInternal(); // FIXME: External
diff --git a/src/D3D8/Direct3DVolume8.cpp b/src/D3D8/Direct3DVolume8.cpp
index aa33ea1..9869068 100644
--- a/src/D3D8/Direct3DVolume8.cpp
+++ b/src/D3D8/Direct3DVolume8.cpp
@@ -23,7 +23,8 @@
namespace D3D8
{
- Direct3DVolume8::Direct3DVolume8(Direct3DDevice8 *device, Direct3DVolumeTexture8 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, bool lockable, unsigned long usage) : Surface(container->getResource(), width, height, depth, translateFormat(format), lockable, false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(lockable), usage(usage)
+ Direct3DVolume8::Direct3DVolume8(Direct3DDevice8 *device, Direct3DVolumeTexture8 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, bool lockable, unsigned long usage)
+ : Surface(container->getResource(), width, height, depth, 0, 1, translateFormat(format), lockable, false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(lockable), usage(usage)
{
resource = new Direct3DResource8(device, D3DRTYPE_VOLUME, memoryUsage(width, height, depth, format));
}
@@ -144,8 +145,8 @@
return INVALIDCALL();
}
- lockedVolume->RowPitch = pitchB(getWidth(), getExternalFormat(), false);
- lockedVolume->SlicePitch = sliceB(getWidth(), getHeight(), getExternalFormat(), false);
+ lockedVolume->RowPitch = pitchB(getWidth(), 0, getExternalFormat(), false);
+ lockedVolume->SlicePitch = sliceB(getWidth(), getHeight(), 0, getExternalFormat(), false);
sw::Lock lock = sw::LOCK_READWRITE;
@@ -194,6 +195,6 @@
unsigned int Direct3DVolume8::memoryUsage(int width, int height, int depth, D3DFORMAT format)
{
- return Surface::size(width, height, depth, translateFormat(format));
+ return Surface::size(width, height, depth, 0, 1, translateFormat(format));
}
}
diff --git a/src/D3D9/Capabilities.cpp b/src/D3D9/Capabilities.cpp
index 2449045..572d983 100644
--- a/src/D3D9/Capabilities.cpp
+++ b/src/D3D9/Capabilities.cpp
@@ -71,13 +71,13 @@
bool Capabilities::Surface::A2R10G10B10 = true;
bool Capabilities::Surface::A2B10G10R10 = true;
bool Capabilities::Surface::A16B16G16R16 = true;
- bool Capabilities::Surface::DXT1 = S3TC_SUPPORT;
- bool Capabilities::Surface::DXT2 = S3TC_SUPPORT;
- bool Capabilities::Surface::DXT3 = S3TC_SUPPORT;
- bool Capabilities::Surface::DXT4 = S3TC_SUPPORT;
- bool Capabilities::Surface::DXT5 = S3TC_SUPPORT;
- bool Capabilities::Surface::ATI1 = S3TC_SUPPORT;
- bool Capabilities::Surface::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::Surface::DXT1 = true;
+ bool Capabilities::Surface::DXT2 = true;
+ bool Capabilities::Surface::DXT3 = true;
+ bool Capabilities::Surface::DXT4 = true;
+ bool Capabilities::Surface::DXT5 = true;
+ bool Capabilities::Surface::ATI1 = true;
+ bool Capabilities::Surface::ATI2 = true;
bool Capabilities::Surface::R16F = true;
bool Capabilities::Surface::G16R16F = true;
bool Capabilities::Surface::A16B16G16R16F = true;
@@ -117,13 +117,13 @@
bool Capabilities::Volume::A2R10G10B10 = true;
bool Capabilities::Volume::A2B10G10R10 = true;
bool Capabilities::Volume::A16B16G16R16 = true;
- bool Capabilities::Volume::DXT1 = S3TC_SUPPORT;
- bool Capabilities::Volume::DXT2 = S3TC_SUPPORT;
- bool Capabilities::Volume::DXT3 = S3TC_SUPPORT;
- bool Capabilities::Volume::DXT4 = S3TC_SUPPORT;
- bool Capabilities::Volume::DXT5 = S3TC_SUPPORT;
- bool Capabilities::Volume::ATI1 = S3TC_SUPPORT;
- bool Capabilities::Volume::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::Volume::DXT1 = true;
+ bool Capabilities::Volume::DXT2 = true;
+ bool Capabilities::Volume::DXT3 = true;
+ bool Capabilities::Volume::DXT4 = true;
+ bool Capabilities::Volume::DXT5 = true;
+ bool Capabilities::Volume::ATI1 = true;
+ bool Capabilities::Volume::ATI2 = true;
bool Capabilities::Volume::R16F = true;
bool Capabilities::Volume::G16R16F = true;
bool Capabilities::Volume::A16B16G16R16F = true;
@@ -195,13 +195,13 @@
bool Capabilities::CubeMap::A2R10G10B10 = true;
bool Capabilities::CubeMap::A2B10G10R10 = true;
bool Capabilities::CubeMap::A16B16G16R16 = true;
- bool Capabilities::CubeMap::DXT1 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::DXT2 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::DXT3 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::DXT4 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::DXT5 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::ATI1 = S3TC_SUPPORT;
- bool Capabilities::CubeMap::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::CubeMap::DXT1 = true;
+ bool Capabilities::CubeMap::DXT2 = true;
+ bool Capabilities::CubeMap::DXT3 = true;
+ bool Capabilities::CubeMap::DXT4 = true;
+ bool Capabilities::CubeMap::DXT5 = true;
+ bool Capabilities::CubeMap::ATI1 = true;
+ bool Capabilities::CubeMap::ATI2 = true;
bool Capabilities::CubeMap::R16F = true;
bool Capabilities::CubeMap::G16R16F = true;
bool Capabilities::CubeMap::A16B16G16R16F = true;
@@ -239,13 +239,13 @@
bool Capabilities::VolumeTexture::A2R10G10B10 = true;
bool Capabilities::VolumeTexture::A2B10G10R10 = true;
bool Capabilities::VolumeTexture::A16B16G16R16 = true;
- bool Capabilities::VolumeTexture::DXT1 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::DXT2 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::DXT3 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::DXT4 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::DXT5 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::ATI1 = S3TC_SUPPORT;
- bool Capabilities::VolumeTexture::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::VolumeTexture::DXT1 = true;
+ bool Capabilities::VolumeTexture::DXT2 = true;
+ bool Capabilities::VolumeTexture::DXT3 = true;
+ bool Capabilities::VolumeTexture::DXT4 = true;
+ bool Capabilities::VolumeTexture::DXT5 = true;
+ bool Capabilities::VolumeTexture::ATI1 = true;
+ bool Capabilities::VolumeTexture::ATI2 = true;
bool Capabilities::VolumeTexture::R16F = true;
bool Capabilities::VolumeTexture::G16R16F = true;
bool Capabilities::VolumeTexture::A16B16G16R16F = true;
@@ -318,13 +318,13 @@
bool Capabilities::Texture::A2R10G10B10 = true;
bool Capabilities::Texture::A2B10G10R10 = true;
bool Capabilities::Texture::A16B16G16R16 = true;
- bool Capabilities::Texture::DXT1 = S3TC_SUPPORT;
- bool Capabilities::Texture::DXT2 = S3TC_SUPPORT;
- bool Capabilities::Texture::DXT3 = S3TC_SUPPORT;
- bool Capabilities::Texture::DXT4 = S3TC_SUPPORT;
- bool Capabilities::Texture::DXT5 = S3TC_SUPPORT;
- bool Capabilities::Texture::ATI1 = S3TC_SUPPORT;
- bool Capabilities::Texture::ATI2 = S3TC_SUPPORT;
+ bool Capabilities::Texture::DXT1 = true;
+ bool Capabilities::Texture::DXT2 = true;
+ bool Capabilities::Texture::DXT3 = true;
+ bool Capabilities::Texture::DXT4 = true;
+ bool Capabilities::Texture::DXT5 = true;
+ bool Capabilities::Texture::ATI1 = true;
+ bool Capabilities::Texture::ATI2 = true;
bool Capabilities::Texture::R16F = true;
bool Capabilities::Texture::G16R16F = true;
bool Capabilities::Texture::A16B16G16R16F = true;
diff --git a/src/D3D9/D3D9.vcxproj b/src/D3D9/D3D9.vcxproj
index 12389e8..71842ec 100644
--- a/src/D3D9/D3D9.vcxproj
+++ b/src/D3D9/D3D9.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -29,43 +29,44 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{F18D5ABF-CA3A-4B74-BDB2-4A1957C86F18}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/src/D3D9/Direct3DCubeTexture9.cpp b/src/D3D9/Direct3DCubeTexture9.cpp
index b0b1925..7d34786 100644
--- a/src/D3D9/Direct3DCubeTexture9.cpp
+++ b/src/D3D9/Direct3DCubeTexture9.cpp
@@ -191,7 +191,7 @@
for(unsigned int face = 0; face < 6; face++)
{
- if(!surfaceLevel[face][0]->hasDirtyMipmaps())
+ if(!surfaceLevel[face][0]->hasDirtyContents())
{
continue;
}
@@ -201,7 +201,7 @@
device->stretchRect(surfaceLevel[face][i], 0, surfaceLevel[face][i + 1], 0, GetAutoGenFilterType());
}
- surfaceLevel[face][0]->cleanMipmaps();
+ surfaceLevel[face][0]->markContentsClean();
}
resource->unlock();
diff --git a/src/D3D9/Direct3DDevice9.cpp b/src/D3D9/Direct3DDevice9.cpp
index 4be7955..d033bcc 100644
--- a/src/D3D9/Direct3DDevice9.cpp
+++ b/src/D3D9/Direct3DDevice9.cpp
@@ -1831,14 +1831,15 @@
static void (__cdecl *blitFunction)(void *dst, void *src);
static sw::Routine *blitRoutine;
- static sw::BlitState blitState = {0};
+ static sw::BlitState blitState = {};
sw::BlitState update;
update.width = sourceDescription.Width;
update.height = sourceDescription.Height;
update.sourceFormat = sw::FORMAT_A8R8G8B8;
+ update.sourceStride = source->getExternalPitchB();
update.destFormat = sw::FORMAT_A8R8G8B8;
- update.stride = dest->getExternalPitchB();
+ update.destStride = dest->getExternalPitchB();
update.cursorHeight = 0;
update.cursorWidth = 0;
@@ -2659,7 +2660,7 @@
void *bitmap = cursorSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
delete cursor;
- cursor = sw::Surface::create(0, width, height, 1, sw::FORMAT_A8R8G8B8, false, false);
+ cursor = sw::Surface::create(nullptr, width, height, 1, 0, 1, sw::FORMAT_A8R8G8B8, false, false);
void *buffer = cursor->lockExternal(0, 0, 0, sw::LOCK_DISCARD, sw::PUBLIC);
memcpy(buffer, bitmap, width * height * sizeof(unsigned int));
@@ -2673,7 +2674,7 @@
}
else
{
- sw::FrameBuffer::setCursorImage(0);
+ sw::FrameBuffer::setCursorImage(nullptr);
}
sw::FrameBuffer::setCursorOrigin(x0, y0);
@@ -6322,7 +6323,8 @@
}
else
{
- renderer->blit(source, sRect, dest, dRect, filter >= D3DTEXF_LINEAR);
+ sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, 0);
+ renderer->blit(source, sRectF, dest, dRect, filter >= D3DTEXF_LINEAR);
}
}
diff --git a/src/D3D9/Direct3DSurface9.cpp b/src/D3D9/Direct3DSurface9.cpp
index fdbc099..8dfa3a8 100644
--- a/src/D3D9/Direct3DSurface9.cpp
+++ b/src/D3D9/Direct3DSurface9.cpp
@@ -76,7 +76,8 @@
return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC) || lockableOverride;
}
- Direct3DSurface9::Direct3DSurface9(Direct3DDevice9 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, bool lockableOverride, unsigned long usage) : Direct3DResource9(device, D3DRTYPE_SURFACE, pool, memoryUsage(width, height, format)), Surface(getParentResource(container), width, height, sampleCount(multiSample, quality), translateFormat(format), isLockable(pool, usage, lockableOverride), (usage & D3DUSAGE_RENDERTARGET) || (usage & D3DUSAGE_DEPTHSTENCIL)), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), quality(quality), lockable(isLockable(pool, usage, lockableOverride)), usage(usage)
+ Direct3DSurface9::Direct3DSurface9(Direct3DDevice9 *device, Unknown *container, int width, int height, D3DFORMAT format, D3DPOOL pool, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, bool lockableOverride, unsigned long usage)
+ : Direct3DResource9(device, D3DRTYPE_SURFACE, pool, memoryUsage(width, height, multiSample, quality, format)), Surface(getParentResource(container), width, height, 1, 0, sampleCount(multiSample, quality), translateFormat(format), isLockable(pool, usage, lockableOverride), (usage & D3DUSAGE_RENDERTARGET) || (usage & D3DUSAGE_DEPTHSTENCIL)), container(container), width(width), height(height), format(format), pool(pool), multiSample(multiSample), quality(quality), lockable(isLockable(pool, usage, lockableOverride)), usage(usage)
{
parentTexture = dynamic_cast<Direct3DBaseTexture9*>(container);
}
@@ -343,7 +344,6 @@
{
switch(format)
{
- #if S3TC_SUPPORT
case D3DFMT_NULL: return sw::FORMAT_NULL;
case D3DFMT_DXT1: return sw::FORMAT_DXT1;
case D3DFMT_DXT2: return sw::FORMAT_DXT3;
@@ -352,7 +352,6 @@
case D3DFMT_DXT5: return sw::FORMAT_DXT5;
case D3DFMT_ATI1: return sw::FORMAT_ATI1;
case D3DFMT_ATI2: return sw::FORMAT_ATI2;
- #endif
case D3DFMT_R3G3B2: return sw::FORMAT_R3G3B2;
case D3DFMT_A8R3G3B2: return sw::FORMAT_A8R3G3B2;
case D3DFMT_X4R4G4B4: return sw::FORMAT_X4R4G4B4;
@@ -410,8 +409,8 @@
return Surface::bytes(translateFormat(format));
}
- unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DFORMAT format)
+ unsigned int Direct3DSurface9::memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, D3DFORMAT format)
{
- return Surface::size(width, height, 1, translateFormat(format));
+ return Surface::size(width, height, 1, 0, sampleCount(multiSample, quality), translateFormat(format));
}
}
diff --git a/src/D3D9/Direct3DSurface9.hpp b/src/D3D9/Direct3DSurface9.hpp
index b7060d8..fa5f481 100644
--- a/src/D3D9/Direct3DSurface9.hpp
+++ b/src/D3D9/Direct3DSurface9.hpp
@@ -64,7 +64,7 @@
static int bytes(D3DFORMAT format);
private:
- static unsigned int memoryUsage(int width, int height, D3DFORMAT format);
+ static unsigned int memoryUsage(int width, int height, D3DMULTISAMPLE_TYPE multiSample, unsigned int quality, D3DFORMAT format);
// Creation parameters
Unknown *const container;
diff --git a/src/D3D9/Direct3DSwapChain9.cpp b/src/D3D9/Direct3DSwapChain9.cpp
index 4b510aa..b446a9f 100644
--- a/src/D3D9/Direct3DSwapChain9.cpp
+++ b/src/D3D9/Direct3DSwapChain9.cpp
@@ -149,9 +149,6 @@
#endif
HWND window = destWindowOverride ? destWindowOverride : presentParameters.hDeviceWindow;
- void *source = backBuffer[0]->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC); // FIXME: External
- sw::Format format = backBuffer[0]->getInternalFormat();
- int stride = backBuffer[0]->getInternalPitchB();
POINT point;
GetCursorPos(&point);
@@ -161,7 +158,7 @@
if(!sourceRect && !destRect) // FIXME: More cases?
{
- frameBuffer->flip(window, source, format, stride);
+ frameBuffer->flip(window, backBuffer[0]);
}
else // FIXME: Check for SWAPEFFECT_COPY
{
@@ -184,11 +181,9 @@
dRect.y1 = destRect->bottom;
}
- frameBuffer->blit(window, source, sourceRect ? &sRect : nullptr, destRect ? &dRect : nullptr, format, stride);
+ frameBuffer->blit(window, backBuffer[0], sourceRect ? &sRect : nullptr, destRect ? &dRect : nullptr);
}
- backBuffer[0]->unlockInternal(); // FIXME: External
-
return D3D_OK;
}
diff --git a/src/D3D9/Direct3DTexture9.cpp b/src/D3D9/Direct3DTexture9.cpp
index a964782..079fba7 100644
--- a/src/D3D9/Direct3DTexture9.cpp
+++ b/src/D3D9/Direct3DTexture9.cpp
@@ -173,7 +173,7 @@
TRACE("");
- if(!(usage & D3DUSAGE_AUTOGENMIPMAP) || !surfaceLevel[0]->hasDirtyMipmaps())
+ if(!(usage & D3DUSAGE_AUTOGENMIPMAP) || !surfaceLevel[0]->hasDirtyContents())
{
return;
}
@@ -185,7 +185,7 @@
device->stretchRect(surfaceLevel[i], 0, surfaceLevel[i + 1], 0, GetAutoGenFilterType());
}
- surfaceLevel[0]->cleanMipmaps();
+ surfaceLevel[0]->markContentsClean();
resource->unlock();
}
diff --git a/src/D3D9/Direct3DVolume9.cpp b/src/D3D9/Direct3DVolume9.cpp
index 4bf498b..ca0d8a8 100644
--- a/src/D3D9/Direct3DVolume9.cpp
+++ b/src/D3D9/Direct3DVolume9.cpp
@@ -30,7 +30,8 @@
return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC);
}
- Direct3DVolume9::Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long usage) : device(device), Surface(container->getResource(), width, height, depth, translateFormat(format), isLockable(pool, usage), false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(isLockable(pool, usage)), usage(usage)
+ Direct3DVolume9::Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long usage)
+ : device(device), Surface(container->getResource(), width, height, depth, 0, 1, translateFormat(format), isLockable(pool, usage), false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(isLockable(pool, usage)), usage(usage)
{
resource = new Direct3DResource9(device, D3DRTYPE_VOLUME, pool, memoryUsage(width, height, depth, format));
resource->bind();
@@ -229,6 +230,6 @@
unsigned int Direct3DVolume9::memoryUsage(int width, int height, int depth, D3DFORMAT format)
{
- return Surface::size(width, height, depth, translateFormat(format));
+ return Surface::size(width, height, depth, 0, 1, translateFormat(format));
}
}
diff --git a/src/D3D9/Direct3DVolumeTexture9.cpp b/src/D3D9/Direct3DVolumeTexture9.cpp
index 35caf43..c9024d1 100644
--- a/src/D3D9/Direct3DVolumeTexture9.cpp
+++ b/src/D3D9/Direct3DVolumeTexture9.cpp
@@ -174,7 +174,7 @@
TRACE("");
- if(!(usage & D3DUSAGE_AUTOGENMIPMAP) || !volumeLevel[0]->hasDirtyMipmaps())
+ if(!(usage & D3DUSAGE_AUTOGENMIPMAP) || !volumeLevel[0]->hasDirtyContents())
{
return;
}
@@ -230,7 +230,7 @@
dest->unlockInternal();
}
- volumeLevel[0]->cleanMipmaps();
+ volumeLevel[0]->markContentsClean();
resource->unlock();
}
diff --git a/src/Main/BUILD.gn b/src/Main/BUILD.gn
index 1f6d69c..99882a9 100644
--- a/src/Main/BUILD.gn
+++ b/src/Main/BUILD.gn
@@ -72,7 +72,6 @@
include_dirs = [
"..",
- "../Common",
]
if (is_mac) {
diff --git a/src/Main/Config.cpp b/src/Main/Config.cpp
index cee01ee..7cb309a 100644
--- a/src/Main/Config.cpp
+++ b/src/Main/Config.cpp
@@ -14,8 +14,8 @@
#include "Config.hpp"
-#include "Thread.hpp"
-#include "Timer.hpp"
+#include "Common/Thread.hpp"
+#include "Common/Timer.hpp"
namespace sw
{
diff --git a/src/Main/Config.hpp b/src/Main/Config.hpp
index b9256ea..ff8bb7e 100644
--- a/src/Main/Config.hpp
+++ b/src/Main/Config.hpp
@@ -20,11 +20,7 @@
#define PERF_HUD 0 // Display time spent on vertex, setup and pixel processing for each thread
#define PERF_PROFILE 0 // Profile various pipeline stages and display the timing in SwiftConfig
-#if defined(_WIN32)
-#define S3TC_SUPPORT 1
-#else
-#define S3TC_SUPPORT 0
-#endif
+#define ASTC_SUPPORT 0
// Worker thread count when not set by SwiftConfig
// 0 = process affinity count (recommended)
@@ -84,11 +80,11 @@
TEXTURE_IMAGE_UNITS = 16,
VERTEX_TEXTURE_IMAGE_UNITS = 16,
TOTAL_IMAGE_UNITS = TEXTURE_IMAGE_UNITS + VERTEX_TEXTURE_IMAGE_UNITS,
- FRAGMENT_UNIFORM_VECTORS = 224,
- VERTEX_UNIFORM_VECTORS = 256,
- MAX_VERTEX_INPUTS = 16,
- MAX_VERTEX_OUTPUTS = 22,
- MAX_FRAGMENT_INPUTS = 20,
+ FRAGMENT_UNIFORM_VECTORS = 227,
+ VERTEX_UNIFORM_VECTORS = 259,
+ MAX_VERTEX_INPUTS = 32,
+ MAX_VERTEX_OUTPUTS = 34,
+ MAX_FRAGMENT_INPUTS = 32,
MAX_FRAGMENT_UNIFORM_BLOCKS = 12,
MAX_VERTEX_UNIFORM_BLOCKS = 12,
MAX_UNIFORM_BUFFER_BINDINGS = MAX_FRAGMENT_UNIFORM_BLOCKS + MAX_VERTEX_UNIFORM_BLOCKS, // Limited to 127 by SourceParameter.bufferIndex in Shader.hpp
diff --git a/src/Main/FrameBuffer.cpp b/src/Main/FrameBuffer.cpp
index e95f766..82dff46 100644
--- a/src/Main/FrameBuffer.cpp
+++ b/src/Main/FrameBuffer.cpp
@@ -14,9 +14,9 @@
#include "FrameBuffer.hpp"
-#include "Timer.hpp"
#include "Renderer/Surface.hpp"
#include "Reactor/Reactor.hpp"
+#include "Common/Timer.hpp"
#include "Common/Debug.hpp"
#include <stdio.h>
@@ -27,7 +27,7 @@
#include <cutils/properties.h>
#endif
-#define ASYNCHRONOUS_BLIT 0 // FIXME: Currently leads to rare race conditions
+#define ASYNCHRONOUS_BLIT false // FIXME: Currently leads to rare race conditions
namespace sw
{
@@ -40,30 +40,18 @@
{
this->topLeftOrigin = topLeftOrigin;
- locked = nullptr;
+ framebuffer = nullptr;
this->width = width;
this->height = height;
- destFormat = FORMAT_X8R8G8B8;
- sourceFormat = FORMAT_X8R8G8B8;
+ format = FORMAT_X8R8G8B8;
stride = 0;
- if(forceWindowed)
- {
- fullscreen = false;
- }
-
- windowed = !fullscreen;
+ windowed = !fullscreen || forceWindowed;
blitFunction = nullptr;
blitRoutine = nullptr;
-
- blitState.width = 0;
- blitState.height = 0;
- blitState.destFormat = FORMAT_X8R8G8B8;
- blitState.sourceFormat = FORMAT_X8R8G8B8;
- blitState.cursorWidth = 0;
- blitState.cursorHeight = 0;
+ blitState = {};
if(ASYNCHRONOUS_BLIT)
{
@@ -86,21 +74,6 @@
delete blitRoutine;
}
- int FrameBuffer::getWidth() const
- {
- return width;
- }
-
- int FrameBuffer::getHeight() const
- {
- return height;
- }
-
- int FrameBuffer::getStride() const
- {
- return stride;
- }
-
void FrameBuffer::setCursorImage(sw::Surface *cursorImage)
{
if(cursorImage)
@@ -130,7 +103,7 @@
cursor.positionY = y;
}
- void FrameBuffer::copy(void *source, Format format, size_t stride)
+ void FrameBuffer::copy(sw::Surface *source)
{
if(!source)
{
@@ -142,15 +115,23 @@
return;
}
- sourceFormat = format;
+ int sourceStride = source->getInternalPitchB();
- if(topLeftOrigin)
+ updateState = {};
+ updateState.width = width;
+ updateState.height = height;
+ updateState.destFormat = format;
+ updateState.destStride = stride;
+ updateState.sourceFormat = source->getInternalFormat();
+ updateState.sourceStride = topLeftOrigin ? sourceStride : -sourceStride;
+ updateState.cursorWidth = cursor.width;
+ updateState.cursorHeight = cursor.height;
+
+ renderbuffer = source->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+
+ if(!topLeftOrigin)
{
- target = source;
- }
- else
- {
- target = (byte*)source + (height - 1) * stride;
+ renderbuffer = (byte*)renderbuffer + (height - 1) * sourceStride;
}
cursor.x = cursor.positionX - cursor.hotspotX;
@@ -166,6 +147,7 @@
copyLocked();
}
+ source->unlockInternal();
unlock();
profiler.nextFrame(); // Assumes every copy() is a full frame
@@ -173,36 +155,26 @@
void FrameBuffer::copyLocked()
{
- BlitState update = {};
- update.width = width;
- update.height = height;
- update.destFormat = destFormat;
- update.sourceFormat = sourceFormat;
- update.stride = stride;
- update.cursorWidth = cursor.width;
- update.cursorHeight = cursor.height;
-
- if(memcmp(&blitState, &update, sizeof(BlitState)) != 0)
+ if(memcmp(&blitState, &updateState, sizeof(BlitState)) != 0)
{
- blitState = update;
+ blitState = updateState;
delete blitRoutine;
blitRoutine = copyRoutine(blitState);
blitFunction = (void(*)(void*, void*, Cursor*))blitRoutine->getEntry();
}
- blitFunction(locked, target, &cursor);
+ blitFunction(framebuffer, renderbuffer, &cursor);
}
Routine *FrameBuffer::copyRoutine(const BlitState &state)
{
const int width = state.width;
const int height = state.height;
- const int width2 = (state.width + 1) & ~1;
const int dBytes = Surface::bytes(state.destFormat);
- const int dStride = state.stride;
+ const int dStride = state.destStride;
const int sBytes = Surface::bytes(state.sourceFormat);
- const int sStride = topLeftOrigin ? (sBytes * width2) : -(sBytes * width2);
+ const int sStride = state.sourceStride;
Function<Void(Pointer<Byte>, Pointer<Byte>, Pointer<Byte>)> function;
{
@@ -253,10 +225,10 @@
case FORMAT_A16B16G16R16:
For(, x < width - 1, x += 2)
{
- UShort4 c0 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 0), 0xC6)) >> 8;
- UShort4 c1 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 8), 0xC6)) >> 8;
+ Short4 c0 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 0), 0xC6)) >> 8;
+ Short4 c1 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 8), 0xC6)) >> 8;
- *Pointer<Int2>(d) = As<Int2>(Pack(c0, c1));
+ *Pointer<Int2>(d) = As<Int2>(PackUnsigned(c0, c1));
s += 2 * sBytes;
d += 2 * dBytes;
@@ -300,9 +272,9 @@
break;
case FORMAT_A16B16G16R16:
{
- UShort4 c = As<UShort4>(Swizzle(*Pointer<Short4>(s), 0xC6)) >> 8;
+ Short4 c = As<UShort4>(Swizzle(*Pointer<Short4>(s), 0xC6)) >> 8;
- *Pointer<Int>(d) = Int(As<Int2>(Pack(c, c)));
+ *Pointer<Int>(d) = Int(As<Int2>(PackUnsigned(c, c)));
}
break;
case FORMAT_R5G6B5:
@@ -361,10 +333,10 @@
case FORMAT_A16B16G16R16:
For(, x < width - 1, x += 2)
{
- UShort4 c0 = *Pointer<UShort4>(s + 0) >> 8;
- UShort4 c1 = *Pointer<UShort4>(s + 8) >> 8;
+ Short4 c0 = *Pointer<UShort4>(s + 0) >> 8;
+ Short4 c1 = *Pointer<UShort4>(s + 8) >> 8;
- *Pointer<Int2>(d) = As<Int2>(Pack(c0, c1));
+ *Pointer<Int2>(d) = As<Int2>(PackUnsigned(c0, c1));
s += 2 * sBytes;
d += 2 * dBytes;
@@ -408,9 +380,9 @@
break;
case FORMAT_A16B16G16R16:
{
- UShort4 c = *Pointer<UShort4>(s) >> 8;
+ Short4 c = *Pointer<UShort4>(s) >> 8;
- *Pointer<Int>(d) = Int(As<Int2>(Pack(c, c)));
+ *Pointer<Int>(d) = Int(As<Int2>(PackUnsigned(c, c)));
}
break;
case FORMAT_R5G6B5:
@@ -503,8 +475,8 @@
break;
case FORMAT_A16B16G16R16:
{
- UShort4 cc = *Pointer<UShort4>(s) >> 8;
- Int c = Int(As<Int2>(Pack(cc, cc)));
+ Short4 cc = *Pointer<UShort4>(s) >> 8;
+ Int c = Int(As<Int2>(PackUnsigned(cc, cc)));
*Pointer<Short>(d) = Short((c & 0x00F80000) >> 19 |
(c & 0x0000FC00) >> 5 |
@@ -615,7 +587,7 @@
{
case FORMAT_X8R8G8B8:
case FORMAT_A8R8G8B8:
- *Pointer<Byte4>(d) = Byte4(Pack(As<UShort4>(c1), As<UShort4>(c1)));
+ *Pointer<Byte4>(d) = Byte4(PackUnsigned(c1, c1));
break;
case FORMAT_X8B8G8R8:
case FORMAT_A8B8G8R8:
@@ -624,12 +596,12 @@
{
c1 = Swizzle(c1, 0xC6);
- *Pointer<Byte4>(d) = Byte4(Pack(As<UShort4>(c1), As<UShort4>(c1)));
+ *Pointer<Byte4>(d) = Byte4(PackUnsigned(c1, c1));
}
break;
case FORMAT_R8G8B8:
{
- Int c = Int(As<Int2>(Pack(As<UShort4>(c1), As<UShort4>(c1))));
+ Int c = Int(As<Int2>(PackUnsigned(c1, c1)));
*Pointer<Byte>(d + 0) = Byte(c >> 0);
*Pointer<Byte>(d + 1) = Byte(c >> 8);
@@ -638,7 +610,7 @@
break;
case FORMAT_R5G6B5:
{
- Int c = Int(As<Int2>(Pack(As<UShort4>(c1), As<UShort4>(c1))));
+ Int c = Int(As<Int2>(PackUnsigned(c1, c1)));
*Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 |
(c & 0x0000FC00) >> 5 |
diff --git a/src/Main/FrameBuffer.hpp b/src/Main/FrameBuffer.hpp
index a18a0b1..dd539e1 100644
--- a/src/Main/FrameBuffer.hpp
+++ b/src/Main/FrameBuffer.hpp
@@ -29,7 +29,8 @@
int height;
Format destFormat;
Format sourceFormat;
- int stride;
+ int destStride;
+ int sourceStride;
int cursorWidth;
int cursorHeight;
};
@@ -41,12 +42,8 @@
virtual ~FrameBuffer() = 0;
- int getWidth() const;
- int getHeight() const;
- int getStride() const;
-
- virtual void flip(void *source, Format sourceFormat, size_t sourceStride) = 0;
- virtual void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) = 0;
+ virtual void flip(sw::Surface *source) = 0;
+ virtual void blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) = 0;
virtual void *lock() = 0;
virtual void unlock() = 0;
@@ -58,22 +55,22 @@
static Routine *copyRoutine(const BlitState &state);
protected:
- void copy(void *source, Format format, size_t stride);
- int width;
- int height;
- Format sourceFormat;
- Format destFormat;
- int stride;
+ void copy(sw::Surface *source);
+
bool windowed;
- void *locked; // Video memory back buffer
+ void *framebuffer; // Native window buffer.
+ int width;
+ int height;
+ int stride;
+ Format format;
private:
void copyLocked();
static void threadFunction(void *parameters);
- void *target; // Render target buffer
+ void *renderbuffer; // Render target buffer.
struct Cursor
{
@@ -92,7 +89,8 @@
void (*blitFunction)(void *dst, void *src, Cursor *cursor);
Routine *blitRoutine;
- BlitState blitState;
+ BlitState blitState; // State of the current blitRoutine.
+ BlitState updateState; // State of the routine to be generated.
static void blend(const BlitState &state, const Pointer<Byte> &d, const Pointer<Byte> &s, const Pointer<Byte> &c);
diff --git a/src/Main/FrameBufferAndroid.cpp b/src/Main/FrameBufferAndroid.cpp
index 16e63ab..9b47171 100644
--- a/src/Main/FrameBufferAndroid.cpp
+++ b/src/Main/FrameBufferAndroid.cpp
@@ -13,7 +13,8 @@
// limitations under the License.
#include "FrameBufferAndroid.hpp"
-#include "GrallocAndroid.hpp"
+
+#include "Common/GrallocAndroid.hpp"
#include <system/window.h>
#include <cutils/log.h>
@@ -60,15 +61,15 @@
nativeWindow->common.decRef(&nativeWindow->common);
}
- void FrameBufferAndroid::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+ void FrameBufferAndroid::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
{
- copy(source, sourceFormat, sourceStride);
+ copy(source);
if(buffer)
{
- if(locked)
+ if(framebuffer)
{
- locked = nullptr;
+ framebuffer = nullptr;
unlock();
}
@@ -85,7 +86,7 @@
if(GrallocModule::getInstance()->lock(buffer->handle,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- 0, 0, buffer->width, buffer->height, &locked) != 0)
+ 0, 0, buffer->width, buffer->height, &framebuffer) != 0)
{
ALOGE("%s failed to lock buffer %p", __FUNCTION__, buffer);
return nullptr;
@@ -100,26 +101,26 @@
switch(buffer->format)
{
- case HAL_PIXEL_FORMAT_RGB_565: destFormat = FORMAT_R5G6B5; break;
- case HAL_PIXEL_FORMAT_RGBA_8888: destFormat = FORMAT_A8B8G8R8; break;
+ case HAL_PIXEL_FORMAT_RGB_565: format = FORMAT_R5G6B5; break;
+ case HAL_PIXEL_FORMAT_RGBA_8888: format = FORMAT_A8B8G8R8; break;
#if ANDROID_PLATFORM_SDK_VERSION > 16
- case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: destFormat = FORMAT_X8B8G8R8; break;
+ case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: format = FORMAT_X8B8G8R8; break;
#endif
- case HAL_PIXEL_FORMAT_RGBX_8888: destFormat = FORMAT_X8B8G8R8; break;
- case HAL_PIXEL_FORMAT_BGRA_8888: destFormat = FORMAT_A8R8G8B8; break;
+ case HAL_PIXEL_FORMAT_RGBX_8888: format = FORMAT_X8B8G8R8; break;
+ case HAL_PIXEL_FORMAT_BGRA_8888: format = FORMAT_A8R8G8B8; break;
case HAL_PIXEL_FORMAT_RGB_888:
// Frame buffers are expected to have 16-bit or 32-bit colors, not 24-bit.
ALOGE("Unsupported frame buffer format RGB_888"); ASSERT(false);
- destFormat = FORMAT_R8G8B8; // Wrong component order.
+ format = FORMAT_R8G8B8; // Wrong component order.
break;
default:
ALOGE("Unsupported frame buffer format %d", buffer->format); ASSERT(false);
- destFormat = FORMAT_NULL;
+ format = FORMAT_NULL;
break;
}
- stride = buffer->stride * Surface::bytes(destFormat);
- return locked;
+ stride = buffer->stride * Surface::bytes(format);
+ return framebuffer;
}
void FrameBufferAndroid::unlock()
@@ -130,7 +131,7 @@
return;
}
- locked = nullptr;
+ framebuffer = nullptr;
if(GrallocModule::getInstance()->unlock(buffer->handle) != 0)
{
diff --git a/src/Main/FrameBufferAndroid.hpp b/src/Main/FrameBufferAndroid.hpp
index 4400188..b71c32b 100644
--- a/src/Main/FrameBufferAndroid.hpp
+++ b/src/Main/FrameBufferAndroid.hpp
@@ -26,12 +26,12 @@
class FrameBufferAndroid : public FrameBuffer
{
public:
- FrameBufferAndroid(ANativeWindow* window, int width, int height);
+ FrameBufferAndroid(ANativeWindow *window, int width, int height);
~FrameBufferAndroid() override;
- void flip(void *source, Format sourceFormat, size_t sourceStride) override {blit(source, 0, 0, sourceFormat, sourceStride);};
- void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+ void flip(sw::Surface *source) override {blit(source, nullptr, nullptr);};
+ void blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override;
void *lock() override;
void unlock() override;
@@ -39,8 +39,8 @@
bool setSwapRectangle(int l, int t, int w, int h);
private:
- ANativeWindow* nativeWindow;
- ANativeWindowBuffer* buffer;
+ ANativeWindow *nativeWindow;
+ ANativeWindowBuffer *buffer;
};
}
diff --git a/src/Main/FrameBufferDD.cpp b/src/Main/FrameBufferDD.cpp
index 9d85ea5..46ed89f 100644
--- a/src/Main/FrameBufferDD.cpp
+++ b/src/Main/FrameBufferDD.cpp
@@ -14,7 +14,7 @@
#include "FrameBufferDD.hpp"
-#include "Debug.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
@@ -38,7 +38,7 @@
frontBuffer = 0;
backBuffer = 0;
- locked = 0;
+ framebuffer = nullptr;
ddraw = LoadLibrary("ddraw.dll");
DirectDrawCreate = (DIRECTDRAWCREATE)GetProcAddress(ddraw, "DirectDrawCreate");
@@ -106,13 +106,13 @@
switch(ddsd.ddpfPixelFormat.dwRGBBitCount)
{
- case 32: destFormat = FORMAT_X8R8G8B8; break;
- case 24: destFormat = FORMAT_R8G8B8; break;
- case 16: destFormat = FORMAT_R5G6B5; break;
- default: destFormat = FORMAT_NULL; break;
+ case 32: format = FORMAT_X8R8G8B8; break;
+ case 24: format = FORMAT_R8G8B8; break;
+ case 16: format = FORMAT_R5G6B5; break;
+ default: format = FORMAT_NULL; break;
}
- if((result != DD_OK && result != DDERR_PRIMARYSURFACEALREADYEXISTS) || (destFormat == FORMAT_NULL))
+ if((result != DD_OK && result != DDERR_PRIMARYSURFACEALREADYEXISTS) || (format == FORMAT_NULL))
{
assert(!"Failed to initialize graphics: Incompatible display mode.");
}
@@ -206,17 +206,17 @@
do
{
- destFormat = FORMAT_X8R8G8B8;
+ format = FORMAT_X8R8G8B8;
result = directDraw->SetDisplayMode(width, height, 32);
if(result == DDERR_INVALIDMODE)
{
- destFormat = FORMAT_R8G8B8;
+ format = FORMAT_R8G8B8;
result = directDraw->SetDisplayMode(width, height, 24);
if(result == DDERR_INVALIDMODE)
{
- destFormat = FORMAT_R5G6B5;
+ format = FORMAT_R5G6B5;
result = directDraw->SetDisplayMode(width, height, 16);
if(result == DDERR_INVALIDMODE)
@@ -250,9 +250,9 @@
updateBounds(windowHandle);
}
- void FrameBufferDD::flip(void *source, Format sourceFormat, size_t sourceStride)
+ void FrameBufferDD::flip(sw::Surface *source)
{
- copy(source, sourceFormat, sourceStride);
+ copy(source);
if(!readySurfaces())
{
@@ -281,9 +281,9 @@
}
}
- void FrameBufferDD::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+ void FrameBufferDD::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
{
- copy(source, sourceFormat, sourceStride);
+ copy(source);
if(!readySurfaces())
{
@@ -320,20 +320,20 @@
}
}
- void FrameBufferDD::flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride)
+ void FrameBufferDD::flip(HWND windowOverride, sw::Surface *source)
{
updateClipper(windowOverride);
updateBounds(windowOverride);
- flip(source, sourceFormat, sourceStride);
+ flip(source);
}
- void FrameBufferDD::blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+ void FrameBufferDD::blit(HWND windowOverride, sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
{
updateClipper(windowOverride);
updateBounds(windowOverride);
- blit(source, sourceRect, destRect, sourceFormat, sourceStride);
+ blit(source, sourceRect, destRect);
}
void FrameBufferDD::screenshot(void *destBuffer)
@@ -404,14 +404,14 @@
void *FrameBufferDD::lock()
{
- if(locked)
+ if(framebuffer)
{
- return locked;
+ return framebuffer;
}
if(!readySurfaces())
{
- return 0;
+ return nullptr;
}
DDSURFACEDESC DDSD;
@@ -425,21 +425,21 @@
height = DDSD.dwHeight;
stride = DDSD.lPitch;
- locked = DDSD.lpSurface;
+ framebuffer = DDSD.lpSurface;
- return locked;
+ return framebuffer;
}
- return 0;
+ return nullptr;
}
void FrameBufferDD::unlock()
{
- if(!locked || !backBuffer) return;
+ if(!framebuffer || !backBuffer) return;
backBuffer->Unlock(0);
- locked = 0;
+ framebuffer = nullptr;
}
void FrameBufferDD::drawText(int x, int y, const char *string, ...)
diff --git a/src/Main/FrameBufferDD.hpp b/src/Main/FrameBufferDD.hpp
index efe6d68..22d76c9 100644
--- a/src/Main/FrameBufferDD.hpp
+++ b/src/Main/FrameBufferDD.hpp
@@ -28,11 +28,11 @@
~FrameBufferDD() override;
- void flip(void *source, Format sourceFormat, size_t sourceStride) override;
- void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+ void flip(sw::Surface *source) override;
+ void blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override;
- void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) override;
- void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+ void flip(HWND windowOverride, sw::Surface *source) override;
+ void blit(HWND windowOverride, sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override;
void *lock() override;
void unlock() override;
diff --git a/src/Main/FrameBufferGDI.cpp b/src/Main/FrameBufferGDI.cpp
index e528d26..90a469e 100644
--- a/src/Main/FrameBufferGDI.cpp
+++ b/src/Main/FrameBufferGDI.cpp
@@ -14,7 +14,7 @@
#include "FrameBufferGDI.hpp"
-#include "Debug.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
@@ -37,7 +37,7 @@
init(this->windowHandle);
- destFormat = FORMAT_X8R8G8B8;
+ format = FORMAT_X8R8G8B8;
}
FrameBufferGDI::~FrameBufferGDI()
@@ -64,21 +64,21 @@
{
stride = width * 4;
- return locked;
+ return framebuffer;
}
void FrameBufferGDI::unlock()
{
}
- void FrameBufferGDI::flip(void *source, Format sourceFormat, size_t sourceStride)
+ void FrameBufferGDI::flip(sw::Surface *source)
{
- blit(source, 0, 0, sourceFormat, sourceStride);
+ blit(source, nullptr, nullptr);
}
- void FrameBufferGDI::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+ void FrameBufferGDI::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
{
- copy(source, sourceFormat, sourceStride);
+ copy(source);
int sourceLeft = sourceRect ? sourceRect->x0 : 0;
int sourceTop = sourceRect ? sourceRect->y0 : 0;
@@ -92,12 +92,12 @@
StretchBlt(windowContext, destLeft, destTop, destWidth, destHeight, bitmapContext, sourceLeft, sourceTop, sourceWidth, sourceHeight, SRCCOPY);
}
- void FrameBufferGDI::flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride)
+ void FrameBufferGDI::flip(HWND windowOverride, sw::Surface *source)
{
- blit(windowOverride, source, 0, 0, sourceFormat, sourceStride);
+ blit(windowOverride, source, nullptr, nullptr);
}
- void FrameBufferGDI::blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+ void FrameBufferGDI::blit(HWND windowOverride, sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
{
if(windowed && windowOverride != 0 && windowOverride != bitmapWindow)
{
@@ -105,7 +105,7 @@
init(windowOverride);
}
- blit(source, sourceRect, destRect, sourceFormat, sourceStride);
+ blit(source, sourceRect, destRect);
}
void FrameBufferGDI::setGammaRamp(GammaRamp *gammaRamp, bool calibrate)
@@ -146,7 +146,7 @@
bitmapInfo.bmiHeader.biWidth = width;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
- bitmap = CreateDIBSection(bitmapContext, &bitmapInfo, DIB_RGB_COLORS, &locked, 0, 0);
+ bitmap = CreateDIBSection(bitmapContext, &bitmapInfo, DIB_RGB_COLORS, &framebuffer, 0, 0);
SelectObject(bitmapContext, bitmap);
updateBounds(window);
diff --git a/src/Main/FrameBufferGDI.hpp b/src/Main/FrameBufferGDI.hpp
index efe44a9..add2504 100644
--- a/src/Main/FrameBufferGDI.hpp
+++ b/src/Main/FrameBufferGDI.hpp
@@ -26,11 +26,11 @@
~FrameBufferGDI() override;
- void flip(void *source, Format sourceFormat, size_t sourceStride) override;
- void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+ void flip(sw::Surface *source) override;
+ void blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override;
- void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) override;
- void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+ void flip(HWND windowOverride, sw::Surface *source) override;
+ void blit(HWND windowOverride, sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override;
void *lock() override;
void unlock() override;
@@ -48,7 +48,7 @@
HDC windowContext;
HDC bitmapContext;
HWND bitmapWindow;
-
+
HBITMAP bitmap;
};
}
diff --git a/src/Main/FrameBufferOSX.hpp b/src/Main/FrameBufferOSX.hpp
index 41f95fe..07f8d63 100644
--- a/src/Main/FrameBufferOSX.hpp
+++ b/src/Main/FrameBufferOSX.hpp
@@ -29,8 +29,8 @@
FrameBufferOSX(CALayer *layer, int width, int height);
~FrameBufferOSX() override;
- void flip(void *source, Format sourceFormat, size_t sourceStride) override;
- void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+ void flip(sw::Surface *source) override;
+ void blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override;
void *lock() override;
void unlock() override;
diff --git a/src/Main/FrameBufferOSX.mm b/src/Main/FrameBufferOSX.mm
index 3a0cfc7..6d58ae7 100644
--- a/src/Main/FrameBufferOSX.mm
+++ b/src/Main/FrameBufferOSX.mm
@@ -25,7 +25,7 @@
: FrameBuffer(width, height, false, false), width(width), height(height),
layer(layer), buffer(nullptr), provider(nullptr), currentImage(nullptr)
{
- destFormat = sw::FORMAT_X8B8G8R8;
+ format = sw::FORMAT_X8B8G8R8;
int bufferSize = width * height * 4 * sizeof(uint8_t);
buffer = new uint8_t[bufferSize];
provider = CGDataProviderCreateWithData(nullptr, buffer, bufferSize, nullptr);
@@ -45,14 +45,14 @@
delete[] buffer;
}
- void FrameBufferOSX::flip(void *source, Format sourceFormat, size_t sourceStride)
+ void FrameBufferOSX::flip(sw::Surface *source)
{
- blit(source, nullptr, nullptr, sourceFormat, sourceStride);
+ blit(source, nullptr, nullptr);
}
- void FrameBufferOSX::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+ void FrameBufferOSX::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
{
- copy(source, sourceFormat, sourceStride);
+ copy(source);
int bytesPerRow = width * 4 * sizeof(uint8_t);
CGImageRef image = CGImageCreate(width, height, 8, 32, bytesPerRow, colorspace, kCGBitmapByteOrder32Big, provider, nullptr, false, kCGRenderingIntentDefault);
@@ -72,13 +72,13 @@
void *FrameBufferOSX::lock()
{
stride = width * 4 * sizeof(uint8_t);
- locked = buffer;
- return locked;
+ framebuffer = buffer;
+ return framebuffer;
};
void FrameBufferOSX::unlock()
{
- locked = nullptr;
+ framebuffer = nullptr;
};
}
diff --git a/src/Main/FrameBufferOzone.cpp b/src/Main/FrameBufferOzone.cpp
index a9de407..95e0729 100644
--- a/src/Main/FrameBufferOzone.cpp
+++ b/src/Main/FrameBufferOzone.cpp
@@ -18,9 +18,9 @@
{
FrameBufferOzone::FrameBufferOzone(intptr_t display, intptr_t window, int width, int height) : FrameBuffer(width, height, false, false)
{
- buffer = sw::Surface::create(width, height, 1, destFormat, nullptr,
- sw::Surface::pitchB(width, destFormat, true),
- sw::Surface::sliceB(width, height, destFormat, true));
+ buffer = sw::Surface::create(width, height, 1, format, nullptr,
+ sw::Surface::pitchB(width, 0, format, true),
+ sw::Surface::sliceB(width, height, 0, format, true));
}
FrameBufferOzone::~FrameBufferOzone()
@@ -30,21 +30,21 @@
void *FrameBufferOzone::lock()
{
- locked = buffer->lockInternal(0, 0, 0, sw::LOCK_READWRITE, sw::PUBLIC);
+ framebuffer = buffer->lockInternal(0, 0, 0, sw::LOCK_READWRITE, sw::PUBLIC);
- return locked;
+ return framebuffer;
}
void FrameBufferOzone::unlock()
{
buffer->unlockInternal();
- locked = nullptr;
+ framebuffer = nullptr;
}
- void FrameBufferOzone::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+ void FrameBufferOzone::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
{
- copy(source, sourceFormat, sourceStride);
+ copy(source);
}
}
diff --git a/src/Main/FrameBufferOzone.hpp b/src/Main/FrameBufferOzone.hpp
index 6843926..0dc9f60 100644
--- a/src/Main/FrameBufferOzone.hpp
+++ b/src/Main/FrameBufferOzone.hpp
@@ -26,8 +26,8 @@
~FrameBufferOzone() override;
- void flip(void *source, Format sourceFormat, size_t sourceStride) override {blit(source, 0, 0, sourceFormat, sourceStride);};
- void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+ void flip(sw::Surface *source) override {blit(source, nullptr, nullptr);};
+ void blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override;
void *lock() override;
void unlock() override;
diff --git a/src/Main/FrameBufferWin.hpp b/src/Main/FrameBufferWin.hpp
index e302195..15c1e0e 100644
--- a/src/Main/FrameBufferWin.hpp
+++ b/src/Main/FrameBufferWin.hpp
@@ -33,11 +33,11 @@
~FrameBufferWin() override;
- void flip(void *source, Format sourceFormat, size_t sourceStride) override = 0;
- void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override = 0;
+ void flip(sw::Surface *source) override = 0;
+ void blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override = 0;
- virtual void flip(HWND windowOverride, void *source, Format sourceFormat, size_t sourceStride) = 0;
- virtual void blit(HWND windowOverride, void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) = 0;
+ virtual void flip(HWND windowOverride, sw::Surface *source) = 0;
+ virtual void blit(HWND windowOverride, sw::Surface *source, const Rect *sourceRect, const Rect *destRect) = 0;
virtual void setGammaRamp(GammaRamp *gammaRamp, bool calibrate) = 0;
virtual void getGammaRamp(GammaRamp *gammaRamp) = 0;
diff --git a/src/Main/FrameBufferX11.cpp b/src/Main/FrameBufferX11.cpp
index a065198..ca0bb4b 100644
--- a/src/Main/FrameBufferX11.cpp
+++ b/src/Main/FrameBufferX11.cpp
@@ -15,6 +15,7 @@
#include "FrameBufferX11.hpp"
#include "libX11.hpp"
+#include "Common/Timer.hpp"
#include <sys/ipc.h>
#include <sys/shm.h>
@@ -84,8 +85,11 @@
if(!mit_shm)
{
- buffer = new char[width * height * 4];
- x_image = libX11->XCreateImage(x_display, visual, depth, ZPixmap, 0, buffer, width, height, 32, width * 4);
+ int bytes_per_line = width * 4;
+ int bytes_per_image = height * bytes_per_line;
+ buffer = new char[bytes_per_image];
+ memset(buffer, 0, bytes_per_image);
+ x_image = libX11->XCreateImage(x_display, visual, depth, ZPixmap, 0, buffer, width, height, 32, bytes_per_line);
}
}
@@ -116,19 +120,19 @@
void *FrameBufferX11::lock()
{
stride = x_image->bytes_per_line;
- locked = buffer;
+ framebuffer = buffer;
- return locked;
+ return framebuffer;
}
void FrameBufferX11::unlock()
{
- locked = nullptr;
+ framebuffer = nullptr;
}
- void FrameBufferX11::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
+ void FrameBufferX11::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
{
- copy(source, sourceFormat, sourceStride);
+ copy(source);
if(!mit_shm)
{
@@ -140,6 +144,36 @@
}
libX11->XSync(x_display, False);
+
+ if(false) // Draw the framerate on screen
+ {
+ static double fpsTime = sw::Timer::seconds();
+ static int frames = -1;
+
+ double time = sw::Timer::seconds();
+ double delta = time - fpsTime;
+ frames++;
+
+ static double FPS = 0.0;
+ static double maxFPS = 0.0;
+
+ if(delta > 1.0)
+ {
+ FPS = frames / delta;
+
+ fpsTime = time;
+ frames = 0;
+
+ if(FPS > maxFPS)
+ {
+ maxFPS = FPS;
+ }
+ }
+
+ char string[256];
+ sprintf(string, "FPS: %.2f (max: %.2f)", FPS, maxFPS);
+ libX11->XDrawString(x_display, x_window, x_gc, 50, 50, string, strlen(string));
+ }
}
}
diff --git a/src/Main/FrameBufferX11.hpp b/src/Main/FrameBufferX11.hpp
index ab0c205..f25487b 100644
--- a/src/Main/FrameBufferX11.hpp
+++ b/src/Main/FrameBufferX11.hpp
@@ -31,8 +31,8 @@
~FrameBufferX11() override;
- void flip(void *source, Format sourceFormat, size_t sourceStride) override {blit(source, 0, 0, sourceFormat, sourceStride);};
- void blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride) override;
+ void flip(sw::Surface *source) override {blit(source, nullptr, nullptr);};
+ void blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect) override;
void *lock() override;
void unlock() override;
diff --git a/src/Main/SwiftConfig.cpp b/src/Main/SwiftConfig.cpp
index b1cc2e9..1c22394 100644
--- a/src/Main/SwiftConfig.cpp
+++ b/src/Main/SwiftConfig.cpp
@@ -14,16 +14,17 @@
#include "SwiftConfig.hpp"
-#include "Configurator.hpp"
-#include "Debug.hpp"
#include "Config.hpp"
-#include "Version.h"
+#include "Common/Configurator.hpp"
+#include "Common/Debug.hpp"
+#include "Common/Version.h"
#include <sstream>
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include <string.h>
+#include <algorithm>
namespace sw
{
@@ -247,7 +248,7 @@
html += "function request()\n";
html += "{\n";
html += "var xhr = new XMLHttpRequest();\n";
- html += "xhr.open('POST', 'http://localhost:8080/swiftshader/profile', true);\n";
+ html += "xhr.open('POST', '/swiftshader/profile', true);\n";
html += "xhr.onreadystatechange = function()\n";
html += "{\n";
html += "if(xhr.readyState == 4 && xhr.status == 200)\n";
diff --git a/src/Main/libX11.cpp b/src/Main/libX11.cpp
index 9c056bf..f3723ff 100644
--- a/src/Main/libX11.cpp
+++ b/src/Main/libX11.cpp
@@ -35,6 +35,7 @@
XCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int))getProcAddress(libX11, "XCreateImage");
XCloseDisplay = (int (*)(Display*))getProcAddress(libX11, "XCloseDisplay");
XPutImage = (int (*)(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int))getProcAddress(libX11, "XPutImage");
+ XDrawString = (int (*)(Display*, Drawable, GC, int, int, char*, int))getProcAddress(libX11, "XDrawString");
XShmQueryExtension = (Bool (*)(Display*))getProcAddress(libXext, "XShmQueryExtension");
XShmCreateImage = (XImage *(*)(Display*, Visual*, unsigned int, int, char*, XShmSegmentInfo*, unsigned int, unsigned int))getProcAddress(libXext, "XShmCreateImage");
diff --git a/src/Main/libX11.hpp b/src/Main/libX11.hpp
index f9f88be..c188386 100644
--- a/src/Main/libX11.hpp
+++ b/src/Main/libX11.hpp
@@ -39,6 +39,7 @@
XImage *(*XCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line);
int (*XCloseDisplay)(Display *display);
int (*XPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height);
+ int (*XDrawString)(Display *display, Drawable d, GC gc, int x, int y, char *string, int length);
Bool (*XShmQueryExtension)(Display *display);
XImage *(*XShmCreateImage)(Display *display, Visual *visual, unsigned int depth, int format, char *data, XShmSegmentInfo *shminfo, unsigned int width, unsigned int height);
diff --git a/src/OpenGL/common/Image.cpp b/src/OpenGL/common/Image.cpp
index f75f92f..280486a 100644
--- a/src/OpenGL/common/Image.cpp
+++ b/src/OpenGL/common/Image.cpp
@@ -14,7 +14,6 @@
#include "Image.hpp"
-#include "../libEGL/Context.hpp"
#include "../libEGL/Texture.hpp"
#include "../common/debug.h"
#include "Common/Math.hpp"
@@ -23,404 +22,11 @@
#include <GLES3/gl3.h>
#include <string.h>
+#include <algorithm>
-namespace
+namespace gl
{
- int getNumBlocks(int w, int h, int blockSizeX, int blockSizeY)
- {
- return ((w + blockSizeX - 1) / blockSizeX) * ((h + blockSizeY - 1) / blockSizeY);
- }
-
- enum DataType
- {
- Bytes_1,
- Bytes_2,
- Bytes_4,
- Bytes_8,
- Bytes_16,
- ByteRGB,
- UByteRGB,
- ShortRGB,
- UShortRGB,
- IntRGB,
- UIntRGB,
- RGB565,
- FloatRGB,
- HalfFloatRGB,
- RGBA4444,
- RGBA5551,
- RGB10A2UI,
- R11G11B10F,
- RGB9E5,
- SRGB,
- SRGBA,
- D16,
- D24,
- D32,
- D32F,
- S8,
- S24_8,
- };
-
- template<DataType dataType>
- void LoadImageRow(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- UNIMPLEMENTED();
- }
-
- template<>
- void LoadImageRow<Bytes_1>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- memcpy(dest + xoffset, source, width);
- }
-
- template<>
- void LoadImageRow<Bytes_2>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- memcpy(dest + xoffset * 2, source, width * 2);
- }
-
- template<>
- void LoadImageRow<Bytes_4>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- memcpy(dest + xoffset * 4, source, width * 4);
- }
-
- template<>
- void LoadImageRow<Bytes_8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- memcpy(dest + xoffset * 8, source, width * 8);
- }
-
- template<>
- void LoadImageRow<Bytes_16>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- memcpy(dest + xoffset * 16, source, width * 16);
- }
-
- template<>
- void LoadImageRow<ByteRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- unsigned char *destB = dest + xoffset * 4;
-
- for(int x = 0; x < width; x++)
- {
- destB[4 * x + 0] = source[x * 3 + 0];
- destB[4 * x + 1] = source[x * 3 + 1];
- destB[4 * x + 2] = source[x * 3 + 2];
- destB[4 * x + 3] = 0x7F;
- }
- }
-
- template<>
- void LoadImageRow<UByteRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- unsigned char *destB = dest + xoffset * 4;
-
- for(int x = 0; x < width; x++)
- {
- destB[4 * x + 0] = source[x * 3 + 0];
- destB[4 * x + 1] = source[x * 3 + 1];
- destB[4 * x + 2] = source[x * 3 + 2];
- destB[4 * x + 3] = 0xFF;
- }
- }
-
- template<>
- void LoadImageRow<ShortRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned short *sourceS = reinterpret_cast<const unsigned short*>(source);
- unsigned short *destS = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
-
- for(int x = 0; x < width; x++)
- {
- destS[4 * x + 0] = sourceS[x * 3 + 0];
- destS[4 * x + 1] = sourceS[x * 3 + 1];
- destS[4 * x + 2] = sourceS[x * 3 + 2];
- destS[4 * x + 3] = 0x7FFF;
- }
- }
-
- template<>
- void LoadImageRow<UShortRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned short *sourceS = reinterpret_cast<const unsigned short*>(source);
- unsigned short *destS = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
-
- for(int x = 0; x < width; x++)
- {
- destS[4 * x + 0] = sourceS[x * 3 + 0];
- destS[4 * x + 1] = sourceS[x * 3 + 1];
- destS[4 * x + 2] = sourceS[x * 3 + 2];
- destS[4 * x + 3] = 0xFFFF;
- }
- }
-
- template<>
- void LoadImageRow<IntRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
- unsigned int *destI = reinterpret_cast<unsigned int*>(dest + xoffset * 16);
-
- for(int x = 0; x < width; x++)
- {
- destI[4 * x + 0] = sourceI[x * 3 + 0];
- destI[4 * x + 1] = sourceI[x * 3 + 1];
- destI[4 * x + 2] = sourceI[x * 3 + 2];
- destI[4 * x + 3] = 0x7FFFFFFF;
- }
- }
-
- template<>
- void LoadImageRow<UIntRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
- unsigned int *destI = reinterpret_cast<unsigned int*>(dest + xoffset * 16);
-
- for(int x = 0; x < width; x++)
- {
- destI[4 * x + 0] = sourceI[x * 3 + 0];
- destI[4 * x + 1] = sourceI[x * 3 + 1];
- destI[4 * x + 2] = sourceI[x * 3 + 2];
- destI[4 * x + 3] = 0xFFFFFFFF;
- }
- }
-
- template<>
- void LoadImageRow<RGB565>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- memcpy(dest + xoffset * 2, source, width * 2);
- }
-
- template<>
- void LoadImageRow<FloatRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const float *sourceF = reinterpret_cast<const float*>(source);
- float *destF = reinterpret_cast<float*>(dest + xoffset * 16);
-
- for(int x = 0; x < width; x++)
- {
- destF[4 * x + 0] = sourceF[x * 3 + 0];
- destF[4 * x + 1] = sourceF[x * 3 + 1];
- destF[4 * x + 2] = sourceF[x * 3 + 2];
- destF[4 * x + 3] = 1.0f;
- }
- }
-
- template<>
- void LoadImageRow<HalfFloatRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
- unsigned short *destH = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
-
- for(int x = 0; x < width; x++)
- {
- destH[4 * x + 0] = sourceH[x * 3 + 0];
- destH[4 * x + 1] = sourceH[x * 3 + 1];
- destH[4 * x + 2] = sourceH[x * 3 + 2];
- destH[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
- }
- }
-
- template<>
- void LoadImageRow<RGBA4444>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source);
- unsigned char *dest4444 = dest + xoffset * 4;
-
- for(int x = 0; x < width; x++)
- {
- unsigned short rgba = source4444[x];
- dest4444[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
- dest4444[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
- dest4444[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
- dest4444[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
- }
- }
-
- template<>
- void LoadImageRow<RGBA5551>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned short *source5551 = reinterpret_cast<const unsigned short*>(source);
- unsigned char *dest5551 = dest + xoffset * 4;
-
- for(int x = 0; x < width; x++)
- {
- unsigned short rgba = source5551[x];
- dest5551[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
- dest5551[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
- dest5551[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- dest5551[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
- }
- }
-
- template<>
- void LoadImageRow<RGB10A2UI>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned int *source1010102U = reinterpret_cast<const unsigned int*>(source);
- unsigned short *dest16U = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
-
- for(int x = 0; x < width; x++)
- {
- unsigned int rgba = source1010102U[x];
- dest16U[4 * x + 0] = (rgba & 0x000003FF);
- dest16U[4 * x + 1] = (rgba & 0x000FFC00) >> 10;
- dest16U[4 * x + 2] = (rgba & 0x3FF00000) >> 20;
- dest16U[4 * x + 3] = (rgba & 0xC0000000) >> 30;
- }
- }
-
- template<>
- void LoadImageRow<R11G11B10F>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const sw::R11G11B10FData *sourceRGB = reinterpret_cast<const sw::R11G11B10FData*>(source);
- float *destF = reinterpret_cast<float*>(dest + xoffset * 16);
-
- for(int x = 0; x < width; x++, sourceRGB++, destF+=4)
- {
- sourceRGB->toRGBFloats(destF);
- destF[3] = 1.0f;
- }
- }
-
- template<>
- void LoadImageRow<RGB9E5>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const sw::RGB9E5Data *sourceRGB = reinterpret_cast<const sw::RGB9E5Data*>(source);
- float *destF = reinterpret_cast<float*>(dest + xoffset * 16);
-
- for(int x = 0; x < width; x++, sourceRGB++, destF += 4)
- {
- sourceRGB->toRGBFloats(destF);
- destF[3] = 1.0f;
- }
- }
-
- template<>
- void LoadImageRow<SRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- dest += xoffset * 4;
-
- for(int x = 0; x < width; x++)
- {
- for(int rgb = 0; rgb < 3; ++rgb)
- {
- *dest++ = sw::sRGB8toLinear8(*source++);
- }
- *dest++ = 255;
- }
- }
-
- template<>
- void LoadImageRow<SRGBA>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- dest += xoffset * 4;
-
- for(int x = 0; x < width; x++)
- {
- for(int rgb = 0; rgb < 3; ++rgb)
- {
- *dest++ = sw::sRGB8toLinear8(*source++);
- }
- *dest++ = *source++;
- }
- }
-
- template<>
- void LoadImageRow<D16>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source);
- float *destF = reinterpret_cast<float*>(dest + xoffset * 4);
-
- for(int x = 0; x < width; x++)
- {
- destF[x] = (float)sourceD16[x] / 0xFFFF;
- }
- }
-
- template<>
- void LoadImageRow<D24>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned int *sourceD24 = reinterpret_cast<const unsigned int*>(source);
- float *destF = reinterpret_cast<float*>(dest + xoffset * 4);
-
- for(int x = 0; x < width; x++)
- {
- destF[x] = (float)(sourceD24[x] & 0xFFFFFF00) / 0xFFFFFF00;
- }
- }
-
- template<>
- void LoadImageRow<D32>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned int *sourceD32 = reinterpret_cast<const unsigned int*>(source);
- float *destF = reinterpret_cast<float*>(dest + xoffset * 4);
-
- for(int x = 0; x < width; x++)
- {
- destF[x] = (float)sourceD32[x] / 0xFFFFFFFF;
- }
- }
-
- template<>
- void LoadImageRow<S8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
- unsigned char *destI = dest + xoffset;
-
- for(int x = 0; x < width; x++)
- {
- destI[x] = static_cast<unsigned char>(sourceI[x] & 0x000000FF); // FIXME: Quad layout
- }
- }
-
- template<>
- void LoadImageRow<D32F>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- struct D32FS8 { float depth32f; unsigned int stencil24_8; };
- const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
- float *destF = reinterpret_cast<float*>(dest + xoffset * 4);
-
- for(int x = 0; x < width; x++)
- {
- destF[x] = sourceD32FS8[x].depth32f;
- }
- }
-
- template<>
- void LoadImageRow<S24_8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
- {
- struct D32FS8 { float depth32f; unsigned int stencil24_8; };
- const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
- unsigned char *destI = dest + xoffset;
-
- for(int x = 0; x < width; x++)
- {
- destI[x] = static_cast<unsigned char>(sourceD32FS8[x].stencil24_8 & 0x000000FF); // FIXME: Quad layout
- }
- }
-
- template<DataType dataType>
- void LoadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, int destPitch, GLsizei destHeight, const void *input, void *buffer)
- {
- for(int z = 0; z < depth; ++z)
- {
- const unsigned char *inputStart = static_cast<const unsigned char*>(input) + (z * inputPitch * inputHeight);
- unsigned char *destStart = static_cast<unsigned char*>(buffer) + ((zoffset + z) * destPitch * destHeight);
- for(int y = 0; y < height; ++y)
- {
- const unsigned char *source = inputStart + y * inputPitch;
- unsigned char *dest = destStart + (y + yoffset) * destPitch;
-
- LoadImageRow<dataType>(source, dest, xoffset, width);
- }
- }
- }
-}
-
-namespace egl
-{
- sw::Format ConvertFormatType(GLenum format, GLenum type)
+ sw::Format ConvertReadFormatType(GLenum format, GLenum type)
{
switch(format)
{
@@ -434,12 +40,6 @@
default: UNREACHABLE(type);
}
break;
- case GL_LUMINANCE8_EXT:
- return sw::FORMAT_L8;
- case GL_LUMINANCE16F_EXT:
- return sw::FORMAT_L16F;
- case GL_LUMINANCE32F_EXT:
- return sw::FORMAT_L32F;
case GL_LUMINANCE_ALPHA:
switch(type)
{
@@ -450,12 +50,6 @@
default: UNREACHABLE(type);
}
break;
- case GL_LUMINANCE8_ALPHA8_EXT:
- return sw::FORMAT_A8L8;
- case GL_LUMINANCE_ALPHA16F_EXT:
- return sw::FORMAT_A16L16F;
- case GL_LUMINANCE_ALPHA32F_EXT:
- return sw::FORMAT_A32L32F;
case GL_RGBA:
switch(type)
{
@@ -465,11 +59,11 @@
case GL_HALF_FLOAT: return sw::FORMAT_A16B16G16R16F;
case GL_HALF_FLOAT_OES: return sw::FORMAT_A16B16G16R16F;
case GL_FLOAT: return sw::FORMAT_A32B32G32R32F;
+ case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: return sw::FORMAT_A2B10G10R10;
default: UNREACHABLE(type);
}
break;
case GL_BGRA_EXT:
- case GL_BGRA8_EXT:
switch(type)
{
case GL_UNSIGNED_BYTE: return sw::FORMAT_A8R8G8B8;
@@ -489,6 +83,26 @@
default: UNREACHABLE(type);
}
break;
+ case GL_RG:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return sw::FORMAT_G8R8;
+ case GL_HALF_FLOAT: return sw::FORMAT_G16R16F;
+ case GL_HALF_FLOAT_OES: return sw::FORMAT_G16R16F;
+ case GL_FLOAT: return sw::FORMAT_G32R32F;
+ default: UNREACHABLE(type);
+ }
+ break;
+ case GL_RED:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return sw::FORMAT_R8;
+ case GL_HALF_FLOAT: return sw::FORMAT_R16F;
+ case GL_HALF_FLOAT_OES: return sw::FORMAT_R16F;
+ case GL_FLOAT: return sw::FORMAT_R32F;
+ default: UNREACHABLE(type);
+ }
+ break;
case GL_ALPHA:
switch(type)
{
@@ -499,12 +113,6 @@
default: UNREACHABLE(type);
}
break;
- case GL_ALPHA8_EXT:
- return sw::FORMAT_A8;
- case GL_ALPHA16F_EXT:
- return sw::FORMAT_A16F;
- case GL_ALPHA32F_EXT:
- return sw::FORMAT_A32F;
case GL_RED_INTEGER:
switch(type)
{
@@ -521,11 +129,20 @@
default: UNREACHABLE(type);
}
break;
+ case GL_RGB_INTEGER:
+ switch(type)
+ {
+ case GL_INT: return sw::FORMAT_X32B32G32R32I;
+ case GL_UNSIGNED_INT: return sw::FORMAT_X32B32G32R32UI;
+ default: UNREACHABLE(type);
+ }
+ break;
case GL_RGBA_INTEGER:
switch(type)
{
case GL_INT: return sw::FORMAT_A32B32G32R32I;
case GL_UNSIGNED_INT: return sw::FORMAT_A32B32G32R32UI;
+ case GL_UNSIGNED_INT_2_10_10_10_REV: return sw::FORMAT_A2B10G10R10UI;
default: UNREACHABLE(type);
}
break;
@@ -535,558 +152,516 @@
case GL_UNSIGNED_SHORT: return sw::FORMAT_D16;
case GL_UNSIGNED_INT_24_8_OES: return sw::FORMAT_D24S8;
case GL_UNSIGNED_INT: return sw::FORMAT_D32;
- case GL_FLOAT: return sw::FORMAT_D32F;
+ case GL_FLOAT: return sw::FORMAT_D32F_LOCKABLE;
default: UNREACHABLE(type);
}
break;
default:
UNREACHABLE(format);
+ break;
}
return sw::FORMAT_NULL;
}
- sw::Format SelectInternalFormat(GLenum format, GLenum type)
+ bool IsUnsizedInternalFormat(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RED:
+ case GL_RG:
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_RED_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RGBA_INTEGER:
+ case GL_BGRA_EXT:
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL:
+ // GL_EXT_sRGB
+ // case GL_SRGB_EXT:
+ // case GL_SRGB_ALPHA_EXT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ GLenum GetBaseInternalFormat(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ // [OpenGL ES 3.0 Table 3.13]
+ case GL_R8: return GL_RED;
+ case GL_R8_SNORM: return GL_RED;
+ case GL_RG8: return GL_RG;
+ case GL_RG8_SNORM: return GL_RG;
+ case GL_RGB8: return GL_RGB;
+ case GL_RGB8_SNORM: return GL_RGB;
+ case GL_RGB565: return GL_RGB;
+ case GL_RGBA4: return GL_RGBA;
+ case GL_RGB5_A1: return GL_RGBA;
+ case GL_RGBA8: return GL_RGBA;
+ case GL_RGBA8_SNORM: return GL_RGBA;
+ case GL_RGB10_A2: return GL_RGBA;
+ case GL_RGB10_A2UI: return GL_RGBA;
+ case GL_SRGB8: return GL_RGB;
+ case GL_SRGB8_ALPHA8: return GL_RGBA;
+ case GL_R16F: return GL_RED;
+ case GL_RG16F: return GL_RG;
+ case GL_RGB16F: return GL_RGB;
+ case GL_RGBA16F: return GL_RGBA;
+ case GL_R32F: return GL_RED;
+ case GL_RG32F: return GL_RG;
+ case GL_RGB32F: return GL_RGB;
+ case GL_RGBA32F: return GL_RGBA;
+ case GL_R11F_G11F_B10F: return GL_RGB;
+ case GL_RGB9_E5: return GL_RGB;
+ case GL_R8I: return GL_RED;
+ case GL_R8UI: return GL_RED;
+ case GL_R16I: return GL_RED;
+ case GL_R16UI: return GL_RED;
+ case GL_R32I: return GL_RED;
+ case GL_R32UI: return GL_RED;
+ case GL_RG8I: return GL_RG;
+ case GL_RG8UI: return GL_RG;
+ case GL_RG16I: return GL_RG;
+ case GL_RG16UI: return GL_RG;
+ case GL_RG32I: return GL_RG;
+ case GL_RG32UI: return GL_RG;
+ case GL_RGB8I: return GL_RGB;
+ case GL_RGB8UI: return GL_RGB;
+ case GL_RGB16I: return GL_RGB;
+ case GL_RGB16UI: return GL_RGB;
+ case GL_RGB32I: return GL_RGB;
+ case GL_RGB32UI: return GL_RGB;
+ case GL_RGBA8I: return GL_RGBA;
+ case GL_RGBA8UI: return GL_RGBA;
+ case GL_RGBA16I: return GL_RGBA;
+ case GL_RGBA16UI: return GL_RGBA;
+ case GL_RGBA32I: return GL_RGBA;
+ case GL_RGBA32UI: return GL_RGBA;
+
+ // GL_EXT_texture_storage
+ case GL_ALPHA8_EXT: return GL_ALPHA;
+ case GL_LUMINANCE8_ALPHA8_EXT: return GL_LUMINANCE_ALPHA;
+ case GL_LUMINANCE8_EXT: return GL_LUMINANCE;
+
+ case GL_BGRA8_EXT: return GL_BGRA_EXT; // GL_APPLE_texture_format_BGRA8888
+
+ case GL_DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT;
+ case GL_DEPTH_COMPONENT32_OES: return GL_DEPTH_COMPONENT;
+ case GL_DEPTH_COMPONENT32F: return GL_DEPTH_COMPONENT;
+ case GL_DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT;
+ case GL_DEPTH32F_STENCIL8: return GL_DEPTH_STENCIL;
+ case GL_DEPTH24_STENCIL8: return GL_DEPTH_STENCIL;
+ case GL_STENCIL_INDEX8: return GL_STENCIL_INDEX_OES;
+ default:
+ UNREACHABLE(internalformat);
+ break;
+ }
+
+ return GL_NONE;
+ }
+
+ GLint GetSizedInternalFormat(GLint internalformat, GLenum type)
+ {
+ if(!IsUnsizedInternalFormat(internalformat))
+ {
+ return internalformat;
+ }
+
+ switch(internalformat)
+ {
+ case GL_RGBA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_RGBA8;
+ case GL_BYTE: return GL_RGBA8_SNORM;
+ case GL_UNSIGNED_SHORT_4_4_4_4: return GL_RGBA4;
+ case GL_UNSIGNED_SHORT_5_5_5_1: return GL_RGB5_A1;
+ case GL_UNSIGNED_INT_2_10_10_10_REV: return GL_RGB10_A2;
+ case GL_FLOAT: return GL_RGBA32F;
+ case GL_HALF_FLOAT: return GL_RGBA16F;
+ case GL_HALF_FLOAT_OES: return GL_RGBA16F;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_RGBA_INTEGER:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_RGBA8UI;
+ case GL_BYTE: return GL_RGBA8I;
+ case GL_UNSIGNED_SHORT: return GL_RGBA16UI;
+ case GL_SHORT: return GL_RGBA16I;
+ case GL_UNSIGNED_INT: return GL_RGBA32UI;
+ case GL_INT: return GL_RGBA32I;
+ case GL_UNSIGNED_INT_2_10_10_10_REV: return GL_RGB10_A2UI;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_RGB:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_RGB8;
+ case GL_BYTE: return GL_RGB8_SNORM;
+ case GL_UNSIGNED_SHORT_5_6_5: return GL_RGB565;
+ case GL_UNSIGNED_INT_10F_11F_11F_REV: return GL_R11F_G11F_B10F;
+ case GL_UNSIGNED_INT_5_9_9_9_REV: return GL_RGB9_E5;
+ case GL_FLOAT: return GL_RGB32F;
+ case GL_HALF_FLOAT: return GL_RGB16F;
+ case GL_HALF_FLOAT_OES: return GL_RGB16F;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_RGB_INTEGER:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_RGB8UI;
+ case GL_BYTE: return GL_RGB8I;
+ case GL_UNSIGNED_SHORT: return GL_RGB16UI;
+ case GL_SHORT: return GL_RGB16I;
+ case GL_UNSIGNED_INT: return GL_RGB32UI;
+ case GL_INT: return GL_RGB32I;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_RG:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_RG8;
+ case GL_BYTE: return GL_RG8_SNORM;
+ case GL_FLOAT: return GL_RG32F;
+ case GL_HALF_FLOAT: return GL_RG16F;
+ case GL_HALF_FLOAT_OES: return GL_RG16F;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_RG_INTEGER:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_RG8UI;
+ case GL_BYTE: return GL_RG8I;
+ case GL_UNSIGNED_SHORT: return GL_RG16UI;
+ case GL_SHORT: return GL_RG16I;
+ case GL_UNSIGNED_INT: return GL_RG32UI;
+ case GL_INT: return GL_RG32I;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_RED:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_R8;
+ case GL_BYTE: return GL_R8_SNORM;
+ case GL_FLOAT: return GL_R32F;
+ case GL_HALF_FLOAT: return GL_R16F;
+ case GL_HALF_FLOAT_OES: return GL_R16F;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_RED_INTEGER:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_R8UI;
+ case GL_BYTE: return GL_R8I;
+ case GL_UNSIGNED_SHORT: return GL_R16UI;
+ case GL_SHORT: return GL_R16I;
+ case GL_UNSIGNED_INT: return GL_R32UI;
+ case GL_INT: return GL_R32I;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_LUMINANCE_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_LUMINANCE8_ALPHA8_EXT;
+ case GL_FLOAT: return GL_LUMINANCE_ALPHA32F_EXT;
+ case GL_HALF_FLOAT: return GL_LUMINANCE_ALPHA16F_EXT;
+ case GL_HALF_FLOAT_OES: return GL_LUMINANCE_ALPHA16F_EXT;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_LUMINANCE:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_LUMINANCE8_EXT;
+ case GL_FLOAT: return GL_LUMINANCE32F_EXT;
+ case GL_HALF_FLOAT: return GL_LUMINANCE16F_EXT;
+ case GL_HALF_FLOAT_OES: return GL_LUMINANCE16F_EXT;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_ALPHA8_EXT;
+ case GL_FLOAT: return GL_ALPHA32F_EXT;
+ case GL_HALF_FLOAT: return GL_ALPHA16F_EXT;
+ case GL_HALF_FLOAT_OES: return GL_ALPHA16F_EXT;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_BGRA_EXT:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: return GL_BGRA8_EXT;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: // Only valid for glReadPixels calls.
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: // Only valid for glReadPixels calls.
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_DEPTH_COMPONENT:
+ switch(type)
+ {
+ case GL_UNSIGNED_SHORT: return GL_DEPTH_COMPONENT16;
+ case GL_UNSIGNED_INT: return GL_DEPTH_COMPONENT32_OES;
+ case GL_FLOAT: return GL_DEPTH_COMPONENT32F;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+ case GL_DEPTH_STENCIL:
+ switch(type)
+ {
+ case GL_UNSIGNED_INT_24_8: return GL_DEPTH24_STENCIL8;
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return GL_DEPTH32F_STENCIL8;
+ default: UNREACHABLE(type); return GL_NONE;
+ }
+
+ // GL_OES_texture_stencil8
+ // case GL_STENCIL_INDEX_OES / GL_UNSIGNED_BYTE: return GL_STENCIL_INDEX8;
+
+ // GL_EXT_sRGB
+ // case GL_SRGB_EXT / GL_UNSIGNED_BYTE: return GL_SRGB8;
+ // case GL_SRGB_ALPHA_EXT / GL_UNSIGNED_BYTE: return GL_SRGB8_ALPHA8;
+
+ default:
+ UNREACHABLE(internalformat);
+ }
+
+ return GL_NONE;
+ }
+
+ sw::Format SelectInternalFormat(GLint format)
{
switch(format)
{
- case GL_ETC1_RGB8_OES:
- return sw::FORMAT_ETC1;
- case GL_COMPRESSED_R11_EAC:
- return sw::FORMAT_R11_EAC;
- case GL_COMPRESSED_SIGNED_R11_EAC:
- return sw::FORMAT_SIGNED_R11_EAC;
- case GL_COMPRESSED_RG11_EAC:
- return sw::FORMAT_RG11_EAC;
- case GL_COMPRESSED_SIGNED_RG11_EAC:
- return sw::FORMAT_SIGNED_RG11_EAC;
- case GL_COMPRESSED_RGB8_ETC2:
- return sw::FORMAT_RGB8_ETC2;
- case GL_COMPRESSED_SRGB8_ETC2:
- return sw::FORMAT_SRGB8_ETC2;
- case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
- return sw::FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
- case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
- return sw::FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
- case GL_COMPRESSED_RGBA8_ETC2_EAC:
- return sw::FORMAT_RGBA8_ETC2_EAC;
- case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
- return sw::FORMAT_SRGB8_ALPHA8_ETC2_EAC;
- case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
- return sw::FORMAT_RGBA_ASTC_4x4_KHR;
- case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
- return sw::FORMAT_RGBA_ASTC_5x4_KHR;
- case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
- return sw::FORMAT_RGBA_ASTC_5x5_KHR;
- case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
- return sw::FORMAT_RGBA_ASTC_6x5_KHR;
- case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
- return sw::FORMAT_RGBA_ASTC_6x6_KHR;
- case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
- return sw::FORMAT_RGBA_ASTC_8x5_KHR;
- case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
- return sw::FORMAT_RGBA_ASTC_8x6_KHR;
- case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
- return sw::FORMAT_RGBA_ASTC_8x8_KHR;
- case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
- return sw::FORMAT_RGBA_ASTC_10x5_KHR;
- case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
- return sw::FORMAT_RGBA_ASTC_10x6_KHR;
- case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
- return sw::FORMAT_RGBA_ASTC_10x8_KHR;
- case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
- return sw::FORMAT_RGBA_ASTC_10x10_KHR;
- case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
- return sw::FORMAT_RGBA_ASTC_12x10_KHR;
- case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
- return sw::FORMAT_RGBA_ASTC_12x12_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR;
- case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
- return sw::FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR;
- #if S3TC_SUPPORT
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- return sw::FORMAT_DXT1;
- case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
- return sw::FORMAT_DXT3;
- case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
- return sw::FORMAT_DXT5;
- #endif
- default:
- break;
- }
+ case GL_RGBA4: return sw::FORMAT_A8B8G8R8;
+ case GL_RGB5_A1: return sw::FORMAT_A8B8G8R8;
+ case GL_RGBA8: return sw::FORMAT_A8B8G8R8;
+ case GL_RGB565: return sw::FORMAT_R5G6B5;
+ case GL_RGB8: return sw::FORMAT_X8B8G8R8;
- switch(type)
- {
- case GL_FLOAT:
- switch(format)
- {
- case GL_ALPHA:
- case GL_ALPHA32F_EXT:
- return sw::FORMAT_A32F;
- case GL_LUMINANCE:
- case GL_LUMINANCE32F_EXT:
- return sw::FORMAT_L32F;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE_ALPHA32F_EXT:
- return sw::FORMAT_A32L32F;
- case GL_RED:
- case GL_R32F:
- return sw::FORMAT_R32F;
- case GL_RG:
- case GL_RG32F:
- return sw::FORMAT_G32R32F;
- case GL_RGB:
- case GL_RGB32F:
- return sw::FORMAT_X32B32G32R32F;
- case GL_RGBA:
- case GL_RGBA32F:
- return sw::FORMAT_A32B32G32R32F;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT32F:
- return sw::FORMAT_D32F;
- default:
- UNREACHABLE(format);
- }
- case GL_HALF_FLOAT:
- case GL_HALF_FLOAT_OES:
- switch(format)
- {
- case GL_ALPHA:
- case GL_ALPHA16F_EXT:
- return sw::FORMAT_A16F;
- case GL_LUMINANCE:
- case GL_LUMINANCE16F_EXT:
- return sw::FORMAT_L16F;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE_ALPHA16F_EXT:
- return sw::FORMAT_A16L16F;
- case GL_RED:
- case GL_R16F:
- return sw::FORMAT_R16F;
- case GL_RG:
- case GL_RG16F:
- return sw::FORMAT_G16R16F;
- case GL_RGB:
- case GL_RGB16F:
- case GL_RGBA:
- case GL_RGBA16F:
- return sw::FORMAT_A16B16G16R16F;
- default:
- UNREACHABLE(format);
- }
- case GL_BYTE:
- switch(format)
- {
- case GL_R8_SNORM:
- case GL_R8:
- case GL_RED:
- return sw::FORMAT_R8I_SNORM;
- case GL_R8I:
- case GL_RED_INTEGER:
- return sw::FORMAT_R8I;
- case GL_RG8_SNORM:
- case GL_RG8:
- case GL_RG:
- return sw::FORMAT_G8R8I_SNORM;
- case GL_RG8I:
- case GL_RG_INTEGER:
- return sw::FORMAT_G8R8I;
- case GL_RGB8_SNORM:
- case GL_RGB8:
- case GL_RGB:
- return sw::FORMAT_X8B8G8R8I_SNORM;
- case GL_RGB8I:
- case GL_RGB_INTEGER:
- return sw::FORMAT_X8B8G8R8I;
- case GL_RGBA8_SNORM:
- case GL_RGBA8:
- case GL_RGBA:
- return sw::FORMAT_A8B8G8R8I_SNORM;
- case GL_RGBA8I:
- case GL_RGBA_INTEGER:
- return sw::FORMAT_A8B8G8R8I;
- default:
- UNREACHABLE(format);
- }
- case GL_UNSIGNED_BYTE:
- switch(format)
- {
- case GL_LUMINANCE:
- case GL_LUMINANCE8_EXT:
- return sw::FORMAT_L8;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE8_ALPHA8_EXT:
- return sw::FORMAT_A8L8;
- case GL_R8_SNORM:
- case GL_R8:
- case GL_RED:
- return sw::FORMAT_R8;
- case GL_R8UI:
- case GL_RED_INTEGER:
- return sw::FORMAT_R8UI;
- case GL_RG8_SNORM:
- case GL_RG8:
- case GL_RG:
- return sw::FORMAT_G8R8;
- case GL_RG8UI:
- case GL_RG_INTEGER:
- return sw::FORMAT_G8R8UI;
- case GL_RGB8_SNORM:
- case GL_RGB8:
- case GL_RGB:
- case GL_SRGB8:
- return sw::FORMAT_X8B8G8R8;
- case GL_RGB8UI:
- case GL_RGB_INTEGER:
- return sw::FORMAT_X8B8G8R8UI;
- case GL_RGBA8_SNORM:
- case GL_RGBA8:
- case GL_RGBA:
- case GL_SRGB8_ALPHA8:
- return sw::FORMAT_A8B8G8R8;
- case GL_RGBA8UI:
- case GL_RGBA_INTEGER:
- return sw::FORMAT_A8B8G8R8UI;
- case GL_BGRA_EXT:
- case GL_BGRA8_EXT:
- return sw::FORMAT_A8R8G8B8;
- case GL_ALPHA:
- case GL_ALPHA8_EXT:
- return sw::FORMAT_A8;
- case SW_YV12_BT601:
- return sw::FORMAT_YV12_BT601;
- case SW_YV12_BT709:
- return sw::FORMAT_YV12_BT709;
- case SW_YV12_JFIF:
- return sw::FORMAT_YV12_JFIF;
- default:
- UNREACHABLE(format);
- }
- case GL_SHORT:
- switch(format)
- {
- case GL_R16I:
- case GL_RED_INTEGER:
- return sw::FORMAT_R16I;
- case GL_RG16I:
- case GL_RG_INTEGER:
- return sw::FORMAT_G16R16I;
- case GL_RGB16I:
- case GL_RGB_INTEGER:
- return sw::FORMAT_X16B16G16R16I;
- case GL_RGBA16I:
- case GL_RGBA_INTEGER:
- return sw::FORMAT_A16B16G16R16I;
- default:
- UNREACHABLE(format);
- }
- case GL_UNSIGNED_SHORT:
- switch(format)
- {
- case GL_R16UI:
- case GL_RED_INTEGER:
- return sw::FORMAT_R16UI;
- case GL_RG16UI:
- case GL_RG_INTEGER:
- return sw::FORMAT_G16R16UI;
- case GL_RGB16UI:
- case GL_RGB_INTEGER:
- return sw::FORMAT_X16B16G16R16UI;
- case GL_RGBA16UI:
- case GL_RGBA_INTEGER:
- return sw::FORMAT_A16B16G16R16UI;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- return sw::FORMAT_D32FS8_TEXTURE;
- default:
- UNREACHABLE(format);
- }
- case GL_INT:
- switch(format)
- {
- case GL_RED_INTEGER:
- case GL_R32I:
- return sw::FORMAT_R32I;
- case GL_RG_INTEGER:
- case GL_RG32I:
- return sw::FORMAT_G32R32I;
- case GL_RGB_INTEGER:
- case GL_RGB32I:
- return sw::FORMAT_X32B32G32R32I;
- case GL_RGBA_INTEGER:
- case GL_RGBA32I:
- return sw::FORMAT_A32B32G32R32I;
- default:
- UNREACHABLE(format);
- }
- case GL_UNSIGNED_INT:
- switch(format)
- {
- case GL_RED_INTEGER:
- case GL_R32UI:
- return sw::FORMAT_R32UI;
- case GL_RG_INTEGER:
- case GL_RG32UI:
- return sw::FORMAT_G32R32UI;
- case GL_RGB_INTEGER:
- case GL_RGB32UI:
- return sw::FORMAT_X32B32G32R32UI;
- case GL_RGBA_INTEGER:
- case GL_RGBA32UI:
- return sw::FORMAT_A32B32G32R32UI;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32_OES:
- return sw::FORMAT_D32FS8_TEXTURE;
- default:
- UNREACHABLE(format);
- }
- case GL_UNSIGNED_INT_24_8_OES:
- if(format == GL_DEPTH_STENCIL || format == GL_DEPTH24_STENCIL8)
- {
- return sw::FORMAT_D32FS8_TEXTURE;
- }
- else UNREACHABLE(format);
- case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
- if(format == GL_DEPTH_STENCIL || format == GL_DEPTH32F_STENCIL8)
- {
- return sw::FORMAT_D32FS8_TEXTURE;
- }
- else UNREACHABLE(format);
- case GL_UNSIGNED_SHORT_4_4_4_4:
- return sw::FORMAT_A8R8G8B8;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- return sw::FORMAT_A8R8G8B8;
- case GL_UNSIGNED_SHORT_5_6_5:
- return sw::FORMAT_R5G6B5;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- if(format == GL_RGB10_A2UI)
- {
- return sw::FORMAT_A16B16G16R16UI;
- }
- else
- {
- return sw::FORMAT_A2B10G10R10;
- }
- case GL_UNSIGNED_INT_10F_11F_11F_REV:
- case GL_UNSIGNED_INT_5_9_9_9_REV:
- return sw::FORMAT_A32B32G32R32F;
- default:
- UNREACHABLE(type);
- }
+ case GL_DEPTH_COMPONENT32F: return sw::FORMAT_D32F_LOCKABLE;
+ case GL_DEPTH_COMPONENT16: return sw::FORMAT_D32F_LOCKABLE;
+ case GL_DEPTH_COMPONENT24: return sw::FORMAT_D32F_LOCKABLE;
+ case GL_DEPTH_COMPONENT32_OES: return sw::FORMAT_D32F_LOCKABLE;
+ case GL_DEPTH24_STENCIL8: return sw::FORMAT_D32FS8_TEXTURE;
+ case GL_DEPTH32F_STENCIL8: return sw::FORMAT_D32FS8_TEXTURE;
+ case GL_STENCIL_INDEX8: return sw::FORMAT_S8;
- return sw::FORMAT_NULL;
+ case GL_R8: return sw::FORMAT_R8;
+ case GL_RG8: return sw::FORMAT_G8R8;
+ case GL_R8I: return sw::FORMAT_R8I;
+ case GL_RG8I: return sw::FORMAT_G8R8I;
+ case GL_RGB8I: return sw::FORMAT_X8B8G8R8I;
+ case GL_RGBA8I: return sw::FORMAT_A8B8G8R8I;
+ case GL_R8UI: return sw::FORMAT_R8UI;
+ case GL_RG8UI: return sw::FORMAT_G8R8UI;
+ case GL_RGB8UI: return sw::FORMAT_X8B8G8R8UI;
+ case GL_RGBA8UI: return sw::FORMAT_A8B8G8R8UI;
+ case GL_R16I: return sw::FORMAT_R16I;
+ case GL_RG16I: return sw::FORMAT_G16R16I;
+ case GL_RGB16I: return sw::FORMAT_X16B16G16R16I;
+ case GL_RGBA16I: return sw::FORMAT_A16B16G16R16I;
+ case GL_R16UI: return sw::FORMAT_R16UI;
+ case GL_RG16UI: return sw::FORMAT_G16R16UI;
+ case GL_RGB16UI: return sw::FORMAT_X16B16G16R16UI;
+ case GL_RGBA16UI: return sw::FORMAT_A16B16G16R16UI;
+ case GL_R32I: return sw::FORMAT_R32I;
+ case GL_RG32I: return sw::FORMAT_G32R32I;
+ case GL_RGB32I: return sw::FORMAT_X32B32G32R32I;
+ case GL_RGBA32I: return sw::FORMAT_A32B32G32R32I;
+ case GL_R32UI: return sw::FORMAT_R32UI;
+ case GL_RG32UI: return sw::FORMAT_G32R32UI;
+ case GL_RGB32UI: return sw::FORMAT_X32B32G32R32UI;
+ case GL_RGBA32UI: return sw::FORMAT_A32B32G32R32UI;
+ case GL_R16F: return sw::FORMAT_R16F;
+ case GL_RG16F: return sw::FORMAT_G16R16F;
+ case GL_R11F_G11F_B10F: return sw::FORMAT_X16B16G16R16F_UNSIGNED;
+ case GL_RGB16F: return sw::FORMAT_X16B16G16R16F;
+ case GL_RGBA16F: return sw::FORMAT_A16B16G16R16F;
+ case GL_R32F: return sw::FORMAT_R32F;
+ case GL_RG32F: return sw::FORMAT_G32R32F;
+ case GL_RGB32F: return sw::FORMAT_X32B32G32R32F;
+ case GL_RGBA32F: return sw::FORMAT_A32B32G32R32F;
+ case GL_RGB10_A2: return sw::FORMAT_A2B10G10R10;
+ case GL_RGB10_A2UI: return sw::FORMAT_A2B10G10R10UI;
+ case GL_SRGB8: return sw::FORMAT_SRGB8_X8;
+ case GL_SRGB8_ALPHA8: return sw::FORMAT_SRGB8_A8;
+
+ case GL_ETC1_RGB8_OES: return sw::FORMAT_ETC1;
+ case GL_COMPRESSED_R11_EAC: return sw::FORMAT_R11_EAC;
+ case GL_COMPRESSED_SIGNED_R11_EAC: return sw::FORMAT_SIGNED_R11_EAC;
+ case GL_COMPRESSED_RG11_EAC: return sw::FORMAT_RG11_EAC;
+ case GL_COMPRESSED_SIGNED_RG11_EAC: return sw::FORMAT_SIGNED_RG11_EAC;
+ case GL_COMPRESSED_RGB8_ETC2: return sw::FORMAT_RGB8_ETC2;
+ case GL_COMPRESSED_SRGB8_ETC2: return sw::FORMAT_SRGB8_ETC2;
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: return sw::FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: return sw::FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ case GL_COMPRESSED_RGBA8_ETC2_EAC: return sw::FORMAT_RGBA8_ETC2_EAC;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: return sw::FORMAT_SRGB8_ALPHA8_ETC2_EAC;
+ case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: return sw::FORMAT_RGBA_ASTC_4x4_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: return sw::FORMAT_RGBA_ASTC_5x4_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: return sw::FORMAT_RGBA_ASTC_5x5_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: return sw::FORMAT_RGBA_ASTC_6x5_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: return sw::FORMAT_RGBA_ASTC_6x6_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: return sw::FORMAT_RGBA_ASTC_8x5_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: return sw::FORMAT_RGBA_ASTC_8x6_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: return sw::FORMAT_RGBA_ASTC_8x8_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: return sw::FORMAT_RGBA_ASTC_10x5_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: return sw::FORMAT_RGBA_ASTC_10x6_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: return sw::FORMAT_RGBA_ASTC_10x8_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: return sw::FORMAT_RGBA_ASTC_10x10_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: return sw::FORMAT_RGBA_ASTC_12x10_KHR;
+ case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: return sw::FORMAT_RGBA_ASTC_12x12_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: return sw::FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return sw::FORMAT_DXT1;
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return sw::FORMAT_DXT1;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return sw::FORMAT_DXT3;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return sw::FORMAT_DXT5;
+
+ case GL_ALPHA32F_EXT: return sw::FORMAT_A32F;
+ case GL_LUMINANCE32F_EXT: return sw::FORMAT_L32F;
+ case GL_LUMINANCE_ALPHA32F_EXT: return sw::FORMAT_A32L32F;
+ case GL_RGB9_E5: return sw::FORMAT_X16B16G16R16F_UNSIGNED;
+ case GL_ALPHA16F_EXT: return sw::FORMAT_A16F;
+ case GL_LUMINANCE16F_EXT: return sw::FORMAT_L16F;
+ case GL_LUMINANCE_ALPHA16F_EXT: return sw::FORMAT_A16L16F;
+ case GL_R8_SNORM: return sw::FORMAT_R8_SNORM;
+ case GL_RG8_SNORM: return sw::FORMAT_G8R8_SNORM;
+ case GL_RGB8_SNORM: return sw::FORMAT_X8B8G8R8_SNORM;
+ case GL_RGBA8_SNORM: return sw::FORMAT_A8B8G8R8_SNORM;
+ case GL_LUMINANCE8_EXT: return sw::FORMAT_L8;
+ case GL_LUMINANCE8_ALPHA8_EXT: return sw::FORMAT_A8L8;
+ case GL_BGRA8_EXT: return sw::FORMAT_A8R8G8B8;
+ case GL_ALPHA8_EXT: return sw::FORMAT_A8;
+
+ case SW_YV12_BT601: return sw::FORMAT_YV12_BT601;
+ case SW_YV12_BT709: return sw::FORMAT_YV12_BT709;
+ case SW_YV12_JFIF: return sw::FORMAT_YV12_JFIF;
+
+ default:
+ UNREACHABLE(format); // Not a sized internal format.
+ return sw::FORMAT_NULL;
+ }
}
- // Returns the size, in bytes, of a single texel in an Image
+ // Returns the size, in bytes, of a single client-side pixel.
+ // OpenGL ES 3.0.5 table 3.2.
static int ComputePixelSize(GLenum format, GLenum type)
{
- switch(type)
+ switch(format)
{
- case GL_BYTE:
- switch(format)
+ case GL_RED:
+ case GL_RED_INTEGER:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ switch(type)
{
- case GL_R8:
- case GL_R8I:
- case GL_R8_SNORM:
- case GL_RED: return sizeof(char);
- case GL_RED_INTEGER: return sizeof(char);
- case GL_RG8:
- case GL_RG8I:
- case GL_RG8_SNORM:
- case GL_RG: return sizeof(char) * 2;
- case GL_RG_INTEGER: return sizeof(char) * 2;
- case GL_RGB8:
- case GL_RGB8I:
- case GL_RGB8_SNORM:
- case GL_RGB: return sizeof(char) * 3;
- case GL_RGB_INTEGER: return sizeof(char) * 3;
- case GL_RGBA8:
- case GL_RGBA8I:
- case GL_RGBA8_SNORM:
- case GL_RGBA: return sizeof(char) * 4;
- case GL_RGBA_INTEGER: return sizeof(char) * 4;
- default: UNREACHABLE(format);
+ case GL_BYTE: return 1;
+ case GL_UNSIGNED_BYTE: return 1;
+ case GL_FLOAT: return 4;
+ case GL_HALF_FLOAT: return 2;
+ case GL_HALF_FLOAT_OES: return 2;
+ case GL_SHORT: return 2;
+ case GL_UNSIGNED_SHORT: return 2;
+ case GL_INT: return 4;
+ case GL_UNSIGNED_INT: return 4;
+ default: UNREACHABLE(type);
}
break;
- case GL_UNSIGNED_BYTE:
- switch(format)
+ case GL_RG:
+ case GL_RG_INTEGER:
+ case GL_LUMINANCE_ALPHA:
+ switch(type)
{
- case GL_R8:
- case GL_R8UI:
- case GL_RED: return sizeof(unsigned char);
- case GL_RED_INTEGER: return sizeof(unsigned char);
- case GL_ALPHA8_EXT:
- case GL_ALPHA: return sizeof(unsigned char);
- case GL_LUMINANCE8_EXT:
- case GL_LUMINANCE: return sizeof(unsigned char);
- case GL_LUMINANCE8_ALPHA8_EXT:
- case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
- case GL_RG8:
- case GL_RG8UI:
- case GL_RG: return sizeof(unsigned char) * 2;
- case GL_RG_INTEGER: return sizeof(unsigned char) * 2;
- case GL_RGB8:
- case GL_RGB8UI:
- case GL_SRGB8:
- case GL_RGB: return sizeof(unsigned char) * 3;
- case GL_RGB_INTEGER: return sizeof(unsigned char) * 3;
- case GL_RGBA8:
- case GL_RGBA8UI:
- case GL_SRGB8_ALPHA8:
- case GL_RGBA: return sizeof(unsigned char) * 4;
- case GL_RGBA_INTEGER: return sizeof(unsigned char) * 4;
- case GL_BGRA_EXT:
- case GL_BGRA8_EXT: return sizeof(unsigned char)* 4;
- default: UNREACHABLE(format);
+ case GL_BYTE: return 2;
+ case GL_UNSIGNED_BYTE: return 2;
+ case GL_FLOAT: return 8;
+ case GL_HALF_FLOAT: return 4;
+ case GL_HALF_FLOAT_OES: return 4;
+ case GL_SHORT: return 4;
+ case GL_UNSIGNED_SHORT: return 4;
+ case GL_INT: return 8;
+ case GL_UNSIGNED_INT: return 8;
+ default: UNREACHABLE(type);
}
break;
- case GL_SHORT:
- switch(format)
+ case GL_RGB:
+ case GL_RGB_INTEGER:
+ switch(type)
{
- case GL_R16I:
- case GL_RED_INTEGER: return sizeof(short);
- case GL_RG16I:
- case GL_RG_INTEGER: return sizeof(short) * 2;
- case GL_RGB16I:
- case GL_RGB_INTEGER: return sizeof(short) * 3;
- case GL_RGBA16I:
- case GL_RGBA_INTEGER: return sizeof(short) * 4;
- default: UNREACHABLE(format);
+ case GL_BYTE: return 3;
+ case GL_UNSIGNED_BYTE: return 3;
+ case GL_UNSIGNED_SHORT_5_6_5: return 2;
+ case GL_UNSIGNED_INT_10F_11F_11F_REV: return 4;
+ case GL_UNSIGNED_INT_5_9_9_9_REV: return 4;
+ case GL_FLOAT: return 12;
+ case GL_HALF_FLOAT: return 6;
+ case GL_HALF_FLOAT_OES: return 6;
+ case GL_SHORT: return 6;
+ case GL_UNSIGNED_SHORT: return 6;
+ case GL_INT: return 12;
+ case GL_UNSIGNED_INT: return 12;
+ default: UNREACHABLE(type);
}
break;
- case GL_UNSIGNED_SHORT:
- switch(format)
+ case GL_RGBA:
+ case GL_RGBA_INTEGER:
+ case GL_BGRA_EXT:
+ switch(type)
{
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT: return sizeof(unsigned short);
- case GL_R16UI:
- case GL_RED_INTEGER: return sizeof(unsigned short);
- case GL_RG16UI:
- case GL_RG_INTEGER: return sizeof(unsigned short) * 2;
- case GL_RGB16UI:
- case GL_RGB_INTEGER: return sizeof(unsigned short) * 3;
- case GL_RGBA16UI:
- case GL_RGBA_INTEGER: return sizeof(unsigned short) * 4;
- default: UNREACHABLE(format);
+ case GL_BYTE: return 4;
+ case GL_UNSIGNED_BYTE: return 4;
+ case GL_UNSIGNED_SHORT_4_4_4_4: return 2;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return 2;
+ case GL_UNSIGNED_SHORT_5_5_5_1: return 2;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return 2;
+ case GL_UNSIGNED_INT_2_10_10_10_REV: return 4;
+ case GL_FLOAT: return 16;
+ case GL_HALF_FLOAT: return 8;
+ case GL_HALF_FLOAT_OES: return 8;
+ case GL_SHORT: return 8;
+ case GL_UNSIGNED_SHORT: return 8;
+ case GL_INT: return 16;
+ case GL_UNSIGNED_INT: return 16;
+ default: UNREACHABLE(type);
}
break;
- case GL_INT:
- switch(format)
+ case GL_DEPTH_COMPONENT:
+ switch(type)
{
- case GL_R32I:
- case GL_RED_INTEGER: return sizeof(int);
- case GL_RG32I:
- case GL_RG_INTEGER: return sizeof(int) * 2;
- case GL_RGB32I:
- case GL_RGB_INTEGER: return sizeof(int) * 3;
- case GL_RGBA32I:
- case GL_RGBA_INTEGER: return sizeof(int) * 4;
- default: UNREACHABLE(format);
+ case GL_FLOAT: return 4;
+ case GL_UNSIGNED_SHORT: return 2;
+ case GL_UNSIGNED_INT: return 4;
+ default: UNREACHABLE(type);
}
break;
- case GL_UNSIGNED_INT:
- switch(format)
+ case GL_DEPTH_STENCIL:
+ switch(type)
{
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32_OES:
- case GL_DEPTH_COMPONENT: return sizeof(unsigned int);
- case GL_R32UI:
- case GL_RED_INTEGER: return sizeof(unsigned int);
- case GL_RG32UI:
- case GL_RG_INTEGER: return sizeof(unsigned int) * 2;
- case GL_RGB32UI:
- case GL_RGB_INTEGER: return sizeof(unsigned int) * 3;
- case GL_RGBA32UI:
- case GL_RGBA_INTEGER: return sizeof(unsigned int) * 4;
- default: UNREACHABLE(format);
+ case GL_UNSIGNED_INT_24_8: return 4;
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return 8;
+ default: UNREACHABLE(type);
}
break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
- return sizeof(unsigned short);
- case GL_UNSIGNED_INT_10F_11F_11F_REV:
- case GL_UNSIGNED_INT_5_9_9_9_REV:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT_24_8_OES:
- return sizeof(unsigned int);
- case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
- return sizeof(float) + sizeof(unsigned int);
- case GL_FLOAT:
- switch(format)
- {
- case GL_DEPTH_COMPONENT32F:
- case GL_DEPTH_COMPONENT: return sizeof(float);
- case GL_ALPHA32F_EXT:
- case GL_ALPHA: return sizeof(float);
- case GL_LUMINANCE32F_EXT:
- case GL_LUMINANCE: return sizeof(float);
- case GL_LUMINANCE_ALPHA32F_EXT:
- case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
- case GL_RED: return sizeof(float);
- case GL_R32F: return sizeof(float);
- case GL_RG: return sizeof(float) * 2;
- case GL_RG32F: return sizeof(float) * 2;
- case GL_RGB: return sizeof(float) * 3;
- case GL_RGB32F: return sizeof(float) * 3;
- case GL_RGBA: return sizeof(float) * 4;
- case GL_RGBA32F: return sizeof(float) * 4;
- default: UNREACHABLE(format);
- }
- break;
- case GL_HALF_FLOAT:
- case GL_HALF_FLOAT_OES:
- switch(format)
- {
- case GL_ALPHA16F_EXT:
- case GL_ALPHA: return sizeof(unsigned short);
- case GL_LUMINANCE16F_EXT:
- case GL_LUMINANCE: return sizeof(unsigned short);
- case GL_LUMINANCE_ALPHA16F_EXT:
- case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
- case GL_RED: return sizeof(unsigned short);
- case GL_R16F: return sizeof(unsigned short);
- case GL_RG: return sizeof(unsigned short) * 2;
- case GL_RG16F: return sizeof(unsigned short) * 2;
- case GL_RGB: return sizeof(unsigned short) * 3;
- case GL_RGB16F: return sizeof(unsigned short) * 3;
- case GL_RGBA: return sizeof(unsigned short) * 4;
- case GL_RGBA16F: return sizeof(unsigned short) * 4;
- default: UNREACHABLE(format);
- }
- break;
- default: UNREACHABLE(type);
+ default:
+ UNREACHABLE(format);
}
return 0;
@@ -1100,10 +675,10 @@
return (rawPitch + alignment - 1) & ~(alignment - 1);
}
- size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, GLint skipImages, GLint skipRows, GLint skipPixels)
+ size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, const gl::PixelStorageModes &storageModes)
{
- GLsizei pitchB = ComputePitch(width, format, type, alignment);
- return (skipImages * height + skipRows) * pitchB + skipPixels * ComputePixelSize(format, type);
+ GLsizei pitchB = ComputePitch(width, format, type, storageModes.alignment);
+ return (storageModes.skipImages * height + storageModes.skipRows) * pitchB + storageModes.skipPixels * ComputePixelSize(format, type);
}
inline GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
@@ -1111,6 +686,11 @@
return ComputeCompressedSize(width, 1, format);
}
+ inline int GetNumCompressedBlocks(int w, int h, int blockSizeX, int blockSizeY)
+ {
+ return ((w + blockSizeX - 1) / blockSizeX) * ((h + blockSizeY - 1) / blockSizeY);
+ }
+
GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
{
switch(format)
@@ -1124,7 +704,7 @@
case GL_COMPRESSED_SRGB8_ETC2:
case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
- return 8 * getNumBlocks(width, height, 4, 4);
+ return 8 * GetNumCompressedBlocks(width, height, 4, 4);
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
case GL_COMPRESSED_RG11_EAC:
@@ -1133,62 +713,450 @@
case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
- return 16 * getNumBlocks(width, height, 4, 4);
+ return 16 * GetNumCompressedBlocks(width, height, 4, 4);
case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
- return 16 * getNumBlocks(width, height, 5, 4);
+ return 16 * GetNumCompressedBlocks(width, height, 5, 4);
case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
- return 16 * getNumBlocks(width, height, 5, 5);
+ return 16 * GetNumCompressedBlocks(width, height, 5, 5);
case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
- return 16 * getNumBlocks(width, height, 6, 5);
+ return 16 * GetNumCompressedBlocks(width, height, 6, 5);
case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
- return 16 * getNumBlocks(width, height, 6, 6);
+ return 16 * GetNumCompressedBlocks(width, height, 6, 6);
case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
- return 16 * getNumBlocks(width, height, 8, 5);
+ return 16 * GetNumCompressedBlocks(width, height, 8, 5);
case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
- return 16 * getNumBlocks(width, height, 8, 6);
+ return 16 * GetNumCompressedBlocks(width, height, 8, 6);
case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
- return 16 * getNumBlocks(width, height, 8, 8);
+ return 16 * GetNumCompressedBlocks(width, height, 8, 8);
case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
- return 16 * getNumBlocks(width, height, 10, 5);
+ return 16 * GetNumCompressedBlocks(width, height, 10, 5);
case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
- return 16 * getNumBlocks(width, height, 10, 6);
+ return 16 * GetNumCompressedBlocks(width, height, 10, 6);
case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
- return 16 * getNumBlocks(width, height, 10, 8);
+ return 16 * GetNumCompressedBlocks(width, height, 10, 8);
case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
- return 16 * getNumBlocks(width, height, 10, 10);
+ return 16 * GetNumCompressedBlocks(width, height, 10, 10);
case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
- return 16 * getNumBlocks(width, height, 12, 10);
+ return 16 * GetNumCompressedBlocks(width, height, 12, 10);
case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
- return 16 * getNumBlocks(width, height, 12, 12);
+ return 16 * GetNumCompressedBlocks(width, height, 12, 12);
default:
+ UNREACHABLE(format);
return 0;
}
}
+}
+
+namespace egl
+{
+ enum TransferType
+ {
+ Bytes,
+ RGB8toRGBX8,
+ RGB16toRGBX16,
+ RGB32toRGBX32,
+ RGB32FtoRGBX32F,
+ RGB16FtoRGBX16F,
+ RGBA4toRGBA8,
+ RGBA5_A1toRGBA8,
+ R11G11B10FtoRGBX16F,
+ RGB9_E5FtoRGBX16F,
+ D16toD32F,
+ D24X8toD32F,
+ D32toD32F,
+ D32FtoD32F_CLAMPED,
+ D32FX32toD32F,
+ X24S8toS8,
+ X56S8toS8,
+ RGBA1010102toRGBA8,
+ RGB8toRGB565,
+ R32FtoR16F,
+ RG32FtoRG16F,
+ RGB32FtoRGB16F,
+ RGB32FtoRGB16F_UNSIGNED,
+ RGBA32FtoRGBA16F
+ };
+
+ template<TransferType transferType>
+ void TransferRow(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes);
+
+ template<>
+ void TransferRow<Bytes>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ memcpy(dest, source, width * bytes);
+ }
+
+ template<>
+ void TransferRow<RGB8toRGBX8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ unsigned char *destB = dest;
+
+ for(int x = 0; x < width; x++)
+ {
+ destB[4 * x + 0] = source[x * 3 + 0];
+ destB[4 * x + 1] = source[x * 3 + 1];
+ destB[4 * x + 2] = source[x * 3 + 2];
+ destB[4 * x + 3] = 0xFF;
+ }
+ }
+
+ template<>
+ void TransferRow<RGB16toRGBX16>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned short *sourceS = reinterpret_cast<const unsigned short*>(source);
+ unsigned short *destS = reinterpret_cast<unsigned short*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destS[4 * x + 0] = sourceS[x * 3 + 0];
+ destS[4 * x + 1] = sourceS[x * 3 + 1];
+ destS[4 * x + 2] = sourceS[x * 3 + 2];
+ destS[4 * x + 3] = 0xFFFF;
+ }
+ }
+
+ template<>
+ void TransferRow<RGB32toRGBX32>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
+ unsigned int *destI = reinterpret_cast<unsigned int*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destI[4 * x + 0] = sourceI[x * 3 + 0];
+ destI[4 * x + 1] = sourceI[x * 3 + 1];
+ destI[4 * x + 2] = sourceI[x * 3 + 2];
+ destI[4 * x + 3] = 0xFFFFFFFF;
+ }
+ }
+
+ template<>
+ void TransferRow<RGB32FtoRGBX32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const float *sourceF = reinterpret_cast<const float*>(source);
+ float *destF = reinterpret_cast<float*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destF[4 * x + 0] = sourceF[x * 3 + 0];
+ destF[4 * x + 1] = sourceF[x * 3 + 1];
+ destF[4 * x + 2] = sourceF[x * 3 + 2];
+ destF[4 * x + 3] = 1.0f;
+ }
+ }
+
+ template<>
+ void TransferRow<RGB16FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned short *sourceH = reinterpret_cast<const unsigned short*>(source);
+ unsigned short *destH = reinterpret_cast<unsigned short*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destH[4 * x + 0] = sourceH[x * 3 + 0];
+ destH[4 * x + 1] = sourceH[x * 3 + 1];
+ destH[4 * x + 2] = sourceH[x * 3 + 2];
+ destH[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16-bit floating-point representation of 1.0
+ }
+ }
+
+ template<>
+ void TransferRow<RGBA4toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source);
+ unsigned char *dest4444 = dest;
+
+ for(int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source4444[x];
+ dest4444[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
+ dest4444[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
+ dest4444[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
+ dest4444[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
+ }
+ }
+
+ template<>
+ void TransferRow<RGBA5_A1toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned short *source5551 = reinterpret_cast<const unsigned short*>(source);
+ unsigned char *dest8888 = dest;
+
+ for(int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source5551[x];
+ dest8888[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest8888[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
+ dest8888[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
+ dest8888[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
+ }
+ }
+
+ template<>
+ void TransferRow<RGBA1010102toRGBA8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned int *source1010102 = reinterpret_cast<const unsigned int*>(source);
+ unsigned char *dest8888 = dest;
+
+ for(int x = 0; x < width; x++)
+ {
+ unsigned int rgba = source1010102[x];
+ dest8888[4 * x + 0] = sw::unorm<8>((rgba & 0x000003FF) * (1.0f / 0x000003FF));
+ dest8888[4 * x + 1] = sw::unorm<8>((rgba & 0x000FFC00) * (1.0f / 0x000FFC00));
+ dest8888[4 * x + 2] = sw::unorm<8>((rgba & 0x3FF00000) * (1.0f / 0x3FF00000));
+ dest8888[4 * x + 3] = sw::unorm<8>((rgba & 0xC0000000) * (1.0f / 0xC0000000));
+ }
+ }
+
+ template<>
+ void TransferRow<RGB8toRGB565>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ unsigned short *dest565 = reinterpret_cast<unsigned short*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ float r = source[3 * x + 0] * (1.0f / 0xFF);
+ float g = source[3 * x + 1] * (1.0f / 0xFF);
+ float b = source[3 * x + 2] * (1.0f / 0xFF);
+ dest565[x] = (sw::unorm<5>(r) << 11) | (sw::unorm<6>(g) << 5) | (sw::unorm<5>(b) << 0);
+ }
+ }
+
+ template<>
+ void TransferRow<R11G11B10FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const sw::R11G11B10F *sourceRGB = reinterpret_cast<const sw::R11G11B10F*>(source);
+ sw::half *destF = reinterpret_cast<sw::half*>(dest);
+
+ for(int x = 0; x < width; x++, sourceRGB++, destF += 4)
+ {
+ sourceRGB->toRGB16F(destF);
+ destF[3] = 1.0f;
+ }
+ }
+
+ template<>
+ void TransferRow<RGB9_E5FtoRGBX16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const sw::RGB9E5 *sourceRGB = reinterpret_cast<const sw::RGB9E5*>(source);
+ sw::half *destF = reinterpret_cast<sw::half*>(dest);
+
+ for(int x = 0; x < width; x++, sourceRGB++, destF += 4)
+ {
+ sourceRGB->toRGB16F(destF);
+ destF[3] = 1.0f;
+ }
+ }
+
+ template<>
+ void TransferRow<R32FtoR16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const float *source32F = reinterpret_cast<const float*>(source);
+ sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ dest16F[x] = source32F[x];
+ }
+ }
+
+ template<>
+ void TransferRow<RG32FtoRG16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const float *source32F = reinterpret_cast<const float*>(source);
+ sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ dest16F[2 * x + 0] = source32F[2 * x + 0];
+ dest16F[2 * x + 1] = source32F[2 * x + 1];
+ }
+ }
+
+ template<>
+ void TransferRow<RGB32FtoRGB16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const float *source32F = reinterpret_cast<const float*>(source);
+ sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ dest16F[4 * x + 0] = source32F[3 * x + 0];
+ dest16F[4 * x + 1] = source32F[3 * x + 1];
+ dest16F[4 * x + 2] = source32F[3 * x + 2];
+ dest16F[4 * x + 3] = 1.0f;
+ }
+ }
+
+ template<>
+ void TransferRow<RGB32FtoRGB16F_UNSIGNED>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const float *source32F = reinterpret_cast<const float*>(source);
+ sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ dest16F[4 * x + 0] = std::max(source32F[3 * x + 0], 0.0f);
+ dest16F[4 * x + 1] = std::max(source32F[3 * x + 1], 0.0f);
+ dest16F[4 * x + 2] = std::max(source32F[3 * x + 2], 0.0f);
+ dest16F[4 * x + 3] = 1.0f;
+ }
+ }
+
+ template<>
+ void TransferRow<RGBA32FtoRGBA16F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const float *source32F = reinterpret_cast<const float*>(source);
+ sw::half *dest16F = reinterpret_cast<sw::half*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ dest16F[4 * x + 0] = source32F[4 * x + 0];
+ dest16F[4 * x + 1] = source32F[4 * x + 1];
+ dest16F[4 * x + 2] = source32F[4 * x + 2];
+ dest16F[4 * x + 3] = source32F[4 * x + 3];
+ }
+ }
+
+ template<>
+ void TransferRow<D16toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned short *sourceD16 = reinterpret_cast<const unsigned short*>(source);
+ float *destF = reinterpret_cast<float*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destF[x] = (float)sourceD16[x] / 0xFFFF;
+ }
+ }
+
+ template<>
+ void TransferRow<D24X8toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned int *sourceD24 = reinterpret_cast<const unsigned int*>(source);
+ float *destF = reinterpret_cast<float*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destF[x] = (float)(sourceD24[x] & 0xFFFFFF00) / 0xFFFFFF00;
+ }
+ }
+
+ template<>
+ void TransferRow<D32toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned int *sourceD32 = reinterpret_cast<const unsigned int*>(source);
+ float *destF = reinterpret_cast<float*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destF[x] = (float)sourceD32[x] / 0xFFFFFFFF;
+ }
+ }
+
+ template<>
+ void TransferRow<D32FtoD32F_CLAMPED>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const float *sourceF = reinterpret_cast<const float*>(source);
+ float *destF = reinterpret_cast<float*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destF[x] = sw::clamp(sourceF[x], 0.0f, 1.0f);
+ }
+ }
+
+ template<>
+ void TransferRow<D32FX32toD32F>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ struct D32FS8 { float depth32f; unsigned int stencil24_8; };
+ const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
+ float *destF = reinterpret_cast<float*>(dest);
+
+ for(int x = 0; x < width; x++)
+ {
+ destF[x] = sw::clamp(sourceD32FS8[x].depth32f, 0.0f, 1.0f);
+ }
+ }
+
+ template<>
+ void TransferRow<X24S8toS8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
+ unsigned char *destI = dest;
+
+ for(int x = 0; x < width; x++)
+ {
+ destI[x] = static_cast<unsigned char>(sourceI[x] & 0x000000FF); // FIXME: Quad layout
+ }
+ }
+
+ template<>
+ void TransferRow<X56S8toS8>(unsigned char *dest, const unsigned char *source, GLsizei width, GLsizei bytes)
+ {
+ struct D32FS8 { float depth32f; unsigned int stencil24_8; };
+ const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
+ unsigned char *destI = dest;
+
+ for(int x = 0; x < width; x++)
+ {
+ destI[x] = static_cast<unsigned char>(sourceD32FS8[x].stencil24_8 & 0x000000FF); // FIXME: Quad layout
+ }
+ }
+
+ struct Rectangle
+ {
+ GLsizei bytes;
+ GLsizei width;
+ GLsizei height;
+ GLsizei depth;
+ int inputPitch;
+ int inputHeight;
+ int destPitch;
+ GLsizei destSlice;
+ };
+
+ template<TransferType transferType>
+ void Transfer(void *buffer, const void *input, const Rectangle &rect)
+ {
+ for(int z = 0; z < rect.depth; z++)
+ {
+ const unsigned char *inputStart = static_cast<const unsigned char*>(input) + (z * rect.inputPitch * rect.inputHeight);
+ unsigned char *destStart = static_cast<unsigned char*>(buffer) + (z * rect.destSlice);
+ for(int y = 0; y < rect.height; y++)
+ {
+ const unsigned char *source = inputStart + y * rect.inputPitch;
+ unsigned char *dest = destStart + y * rect.destPitch;
+
+ TransferRow<transferType>(dest, source, rect.width, rect.bytes);
+ }
+ }
+ }
class ImageImplementation : public Image
{
public:
- ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
- : Image(parentTexture, width, height, format, type) {}
- ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
- : Image(parentTexture, width, height, depth, format, type) {}
- ImageImplementation(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
- : Image(width, height, format, type, pitchP) {}
- ImageImplementation(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
- : Image(width, height, internalFormat, multiSampleDepth, lockable) {}
+ ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLint internalformat)
+ : Image(parentTexture, width, height, internalformat) {}
+ ImageImplementation(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLint internalformat)
+ : Image(parentTexture, width, height, depth, border, internalformat) {}
+ ImageImplementation(GLsizei width, GLsizei height, GLint internalformat, int pitchP)
+ : Image(width, height, internalformat, pitchP) {}
+ ImageImplementation(GLsizei width, GLsizei height, GLint internalformat, int multiSampleDepth, bool lockable)
+ : Image(width, height, internalformat, multiSampleDepth, lockable) {}
~ImageImplementation() override
{
@@ -1211,24 +1179,24 @@
}
};
- Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
+ Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLint internalformat)
{
- return new ImageImplementation(parentTexture, width, height, format, type);
+ return new ImageImplementation(parentTexture, width, height, internalformat);
}
- Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
+ Image *Image::create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLint internalformat)
{
- return new ImageImplementation(parentTexture, width, height, depth, format, type);
+ return new ImageImplementation(parentTexture, width, height, depth, border, internalformat);
}
- Image *Image::create(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
+ Image *Image::create(GLsizei width, GLsizei height, GLint internalformat, int pitchP)
{
- return new ImageImplementation(width, height, format, type, pitchP);
+ return new ImageImplementation(width, height, internalformat, pitchP);
}
- Image *Image::create(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
+ Image *Image::create(GLsizei width, GLsizei height, GLint internalformat, int multiSampleDepth, bool lockable)
{
- return new ImageImplementation(width, height, internalFormat, multiSampleDepth, lockable);
+ return new ImageImplementation(width, height, internalformat, multiSampleDepth, lockable);
}
Image::~Image()
@@ -1287,434 +1255,381 @@
return parentTexture == parent;
}
- void Image::loadImageData(Context *context, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input)
+ void Image::loadImageData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer)
{
- sw::Format selectedInternalFormat = SelectInternalFormat(format, type);
- if(selectedInternalFormat == sw::FORMAT_NULL)
+ Rectangle rect;
+ rect.bytes = gl::ComputePixelSize(format, type);
+ rect.width = width;
+ rect.height = height;
+ rect.depth = depth;
+ rect.inputPitch = inputPitch;
+ rect.inputHeight = inputHeight;
+ rect.destPitch = getPitch();
+ rect.destSlice = getSlice();
+
+ // [OpenGL ES 3.0.5] table 3.2 and 3.3.
+ switch(format)
{
- return;
- }
-
- GLsizei inputWidth = (unpackInfo.rowLength == 0) ? width : unpackInfo.rowLength;
- GLsizei inputPitch = ComputePitch(inputWidth, format, type, unpackInfo.alignment);
- GLsizei inputHeight = (unpackInfo.imageHeight == 0) ? height : unpackInfo.imageHeight;
- input = ((char*)input) + ComputePackingOffset(format, type, inputWidth, inputHeight, unpackInfo.alignment, unpackInfo.skipImages, unpackInfo.skipRows, unpackInfo.skipPixels);
-
- if(selectedInternalFormat == internalFormat)
- {
- void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
-
- if(buffer)
+ case GL_RGBA:
+ switch(type)
{
- switch(type)
+ case GL_UNSIGNED_BYTE:
+ switch(internalformat)
{
- case GL_BYTE:
- switch(format)
- {
- case GL_R8:
- case GL_R8I:
- case GL_R8_SNORM:
- case GL_RED:
- case GL_RED_INTEGER:
- case GL_ALPHA:
- case GL_ALPHA8_EXT:
- case GL_LUMINANCE:
- case GL_LUMINANCE8_EXT:
- LoadImageData<Bytes_1>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RG8:
- case GL_RG8I:
- case GL_RG8_SNORM:
- case GL_RG:
- case GL_RG_INTEGER:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE8_ALPHA8_EXT:
- LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB8:
- case GL_RGB8I:
- case GL_RGB8_SNORM:
- case GL_RGB:
- case GL_RGB_INTEGER:
- LoadImageData<ByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGBA8:
- case GL_RGBA8I:
- case GL_RGBA8_SNORM:
- case GL_RGBA:
- case GL_RGBA_INTEGER:
- case GL_BGRA_EXT:
- case GL_BGRA8_EXT:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_BYTE:
- switch(format)
- {
- case GL_R8:
- case GL_R8UI:
- case GL_R8_SNORM:
- case GL_RED:
- case GL_RED_INTEGER:
- case GL_ALPHA:
- case GL_ALPHA8_EXT:
- case GL_LUMINANCE:
- case GL_LUMINANCE8_EXT:
- LoadImageData<Bytes_1>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RG8:
- case GL_RG8UI:
- case GL_RG8_SNORM:
- case GL_RG:
- case GL_RG_INTEGER:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE8_ALPHA8_EXT:
- LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB8:
- case GL_RGB8UI:
- case GL_RGB8_SNORM:
- case GL_RGB:
- case GL_RGB_INTEGER:
- LoadImageData<UByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGBA8:
- case GL_RGBA8UI:
- case GL_RGBA8_SNORM:
- case GL_RGBA:
- case GL_RGBA_INTEGER:
- case GL_BGRA_EXT:
- case GL_BGRA8_EXT:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_SRGB8:
- LoadImageData<SRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_SRGB8_ALPHA8:
- LoadImageData<SRGBA>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- switch(format)
- {
- case GL_RGB565:
- case GL_RGB:
- LoadImageData<RGB565>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- switch(format)
- {
- case GL_RGBA4:
- case GL_RGBA:
- LoadImageData<RGBA4444>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- switch(format)
- {
- case GL_RGB5_A1:
- case GL_RGBA:
- LoadImageData<RGBA5551>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_INT_10F_11F_11F_REV:
- switch(format)
- {
- case GL_R11F_G11F_B10F:
- case GL_RGB:
- LoadImageData<R11G11B10F>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_INT_5_9_9_9_REV:
- switch(format)
- {
- case GL_RGB9_E5:
- case GL_RGB:
- LoadImageData<RGB9E5>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- switch(format)
- {
- case GL_RGB10_A2UI:
- LoadImageData<RGB10A2UI>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB10_A2:
- case GL_RGBA:
- case GL_RGBA_INTEGER:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_FLOAT:
- switch(format)
- {
- // float textures are converted to RGBA, not BGRA
- case GL_ALPHA:
- case GL_ALPHA32F_EXT:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_LUMINANCE:
- case GL_LUMINANCE32F_EXT:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE_ALPHA32F_EXT:
- LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RED:
- case GL_R32F:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RG:
- case GL_RG32F:
- LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB:
- case GL_RGB32F:
- LoadImageData<FloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGBA:
- case GL_RGBA32F:
- LoadImageData<Bytes_16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT32F:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_HALF_FLOAT:
- case GL_HALF_FLOAT_OES:
- switch(format)
- {
- case GL_ALPHA:
- case GL_ALPHA16F_EXT:
- LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_LUMINANCE:
- case GL_LUMINANCE16F_EXT:
- LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE_ALPHA16F_EXT:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RED:
- case GL_R16F:
- LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RG:
- case GL_RG16F:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB:
- case GL_RGB16F:
- LoadImageData<HalfFloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGBA:
- case GL_RGBA16F:
- LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_SHORT:
- switch(format)
- {
- case GL_R16I:
- case GL_RED:
- case GL_RED_INTEGER:
- case GL_ALPHA:
- case GL_LUMINANCE:
- LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RG16I:
- case GL_RG:
- case GL_RG_INTEGER:
- case GL_LUMINANCE_ALPHA:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB16I:
- case GL_RGB:
- case GL_RGB_INTEGER:
- LoadImageData<ShortRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGBA16I:
- case GL_RGBA:
- case GL_RGBA_INTEGER:
- case GL_BGRA_EXT:
- case GL_BGRA8_EXT:
- LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_SHORT:
- switch(format)
- {
- case GL_R16UI:
- case GL_RED:
- case GL_RED_INTEGER:
- case GL_ALPHA:
- case GL_LUMINANCE:
- LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RG16UI:
- case GL_RG:
- case GL_RG_INTEGER:
- case GL_LUMINANCE_ALPHA:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB16UI:
- case GL_RGB:
- case GL_RGB_INTEGER:
- LoadImageData<UShortRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGBA16UI:
- case GL_RGBA:
- case GL_RGBA_INTEGER:
- case GL_BGRA_EXT:
- case GL_BGRA8_EXT:
- LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- LoadImageData<D16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_INT:
- switch(format)
- {
- case GL_R32I:
- case GL_RED:
- case GL_RED_INTEGER:
- case GL_ALPHA:
- case GL_LUMINANCE:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RG32I:
- case GL_RG:
- case GL_RG_INTEGER:
- case GL_LUMINANCE_ALPHA:
- LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB32I:
- case GL_RGB:
- case GL_RGB_INTEGER:
- LoadImageData<IntRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGBA32I:
- case GL_RGBA:
- case GL_RGBA_INTEGER:
- case GL_BGRA_EXT:
- case GL_BGRA8_EXT:
- LoadImageData<Bytes_16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_INT:
- switch(format)
- {
- case GL_R32UI:
- case GL_RED:
- case GL_RED_INTEGER:
- case GL_ALPHA:
- case GL_LUMINANCE:
- LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RG32UI:
- case GL_RG:
- case GL_RG_INTEGER:
- case GL_LUMINANCE_ALPHA:
- LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGB32UI:
- case GL_RGB:
- case GL_RGB_INTEGER:
- LoadImageData<UIntRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_RGBA32UI:
- case GL_RGBA:
- case GL_RGBA_INTEGER:
- case GL_BGRA_EXT:
- case GL_BGRA8_EXT:
- LoadImageData<Bytes_16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32_OES:
- case GL_DEPTH_COMPONENT:
- LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
- break;
- default: UNREACHABLE(format);
- }
- break;
- case GL_UNSIGNED_INT_24_8_OES:
- loadD24S8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
- break;
- case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
- loadD32FS8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
- break;
- default: UNREACHABLE(type);
+ case GL_RGBA8:
+ case GL_SRGB8_ALPHA8:
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_RGB5_A1:
+ case GL_RGBA4:
+ ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A8B8G8R8);
+ return Transfer<Bytes>(buffer, input, rect);
+ default:
+ UNREACHABLE(internalformat);
}
+ case GL_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA8_SNORM && getExternalFormat() == sw::FORMAT_A8B8G8R8_SNORM);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA4 && getExternalFormat() == sw::FORMAT_A8B8G8R8);
+ return Transfer<RGBA4toRGBA8>(buffer, input, rect);
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ ASSERT_OR_RETURN(internalformat == GL_RGB5_A1 && getExternalFormat() == sw::FORMAT_A8B8G8R8);
+ return Transfer<RGBA5_A1toRGBA8>(buffer, input, rect);
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ switch(internalformat)
+ {
+ case GL_RGB10_A2:
+ ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A2B10G10R10);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_RGB5_A1:
+ ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_A8B8G8R8);
+ return Transfer<RGBA1010102toRGBA8>(buffer, input, rect);
+ default:
+ UNREACHABLE(internalformat);
+ }
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA16F && getExternalFormat() == sw::FORMAT_A16B16G16R16F);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_FLOAT:
+ switch(internalformat)
+ {
+ case GL_RGBA32F: return Transfer<Bytes>(buffer, input, rect);
+ case GL_RGBA16F: return Transfer<RGBA32FtoRGBA16F>(buffer, input, rect);
+ default: UNREACHABLE(internalformat);
+ }
+ default:
+ UNREACHABLE(type);
}
-
- unlock();
- }
- else
- {
- sw::Surface *source = sw::Surface::create(width, height, depth, ConvertFormatType(format, type), const_cast<void*>(input), inputPitch, inputPitch * inputHeight);
- sw::Rect sourceRect(0, 0, width, height);
- sw::Rect destRect(xoffset, yoffset, xoffset + width, yoffset + height);
- context->blit(source, sourceRect, this, destRect);
- delete source;
+ case GL_RGBA_INTEGER:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA8UI && getExternalFormat() == sw::FORMAT_A8B8G8R8UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA8I && getExternalFormat() == sw::FORMAT_A8B8G8R8I);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_SHORT:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA16UI && getExternalFormat() == sw::FORMAT_A16B16G16R16UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_SHORT:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA16I && getExternalFormat() == sw::FORMAT_A16B16G16R16I);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_INT:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA32UI && getExternalFormat() == sw::FORMAT_A32B32G32R32UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_INT:
+ ASSERT_OR_RETURN(internalformat == GL_RGBA32I && getExternalFormat() == sw::FORMAT_A32B32G32R32I);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ ASSERT_OR_RETURN(internalformat == GL_RGB10_A2UI && getExternalFormat() == sw::FORMAT_A2B10G10R10UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_BGRA_EXT:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_BGRA8_EXT && getExternalFormat() == sw::FORMAT_A8R8G8B8);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: // Only valid for glReadPixels calls.
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: // Only valid for glReadPixels calls.
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_RGB:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ switch(internalformat)
+ {
+ case GL_RGB8: return Transfer<RGB8toRGBX8>(buffer, input, rect);
+ case GL_SRGB8: return Transfer<RGB8toRGBX8>(buffer, input, rect);
+ case GL_RGB565: return Transfer<RGB8toRGB565>(buffer, input, rect);
+ default: UNREACHABLE(internalformat);
+ }
+ case GL_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_RGB8_SNORM && getExternalFormat() == sw::FORMAT_X8B8G8R8_SNORM);
+ return Transfer<RGB8toRGBX8>(buffer, input, rect);
+ case GL_UNSIGNED_SHORT_5_6_5:
+ ASSERT_OR_RETURN(internalformat == GL_RGB565 && getExternalFormat() == sw::FORMAT_R5G6B5);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ ASSERT_OR_RETURN(internalformat == GL_R11F_G11F_B10F && getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
+ return Transfer<R11G11B10FtoRGBX16F>(buffer, input, rect);
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ ASSERT_OR_RETURN(internalformat == GL_RGB9_E5 && getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
+ return Transfer<RGB9_E5FtoRGBX16F>(buffer, input, rect);
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ switch(internalformat)
+ {
+ case GL_RGB16F:
+ ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F);
+ return Transfer<RGB16FtoRGBX16F>(buffer, input, rect);
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
+ return Transfer<RGB16FtoRGBX16F>(buffer, input, rect);
+ default:
+ UNREACHABLE(internalformat);
+ }
+ case GL_FLOAT:
+ switch(internalformat)
+ {
+ case GL_RGB32F:
+ ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X32B32G32R32F);
+ return Transfer<RGB32FtoRGBX32F>(buffer, input, rect);
+ case GL_RGB16F:
+ ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F);
+ return Transfer<RGB32FtoRGB16F>(buffer, input, rect);
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ ASSERT_OR_RETURN(getExternalFormat() == sw::FORMAT_X16B16G16R16F_UNSIGNED);
+ return Transfer<RGB32FtoRGB16F_UNSIGNED>(buffer, input, rect);
+ default:
+ UNREACHABLE(internalformat);
+ }
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_RGB_INTEGER:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_RGB8UI && getExternalFormat() == sw::FORMAT_X8B8G8R8UI);
+ return Transfer<RGB8toRGBX8>(buffer, input, rect);
+ case GL_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_RGB8I && getExternalFormat() == sw::FORMAT_X8B8G8R8I);
+ return Transfer<RGB8toRGBX8>(buffer, input, rect);
+ case GL_UNSIGNED_SHORT:
+ ASSERT_OR_RETURN(internalformat == GL_RGB16UI && getExternalFormat() == sw::FORMAT_X16B16G16R16UI);
+ return Transfer<RGB16toRGBX16>(buffer, input, rect);
+ case GL_SHORT:
+ ASSERT_OR_RETURN(internalformat == GL_RGB16I && getExternalFormat() == sw::FORMAT_X16B16G16R16I);
+ return Transfer<RGB16toRGBX16>(buffer, input, rect);
+ case GL_UNSIGNED_INT:
+ ASSERT_OR_RETURN(internalformat == GL_RGB32UI && getExternalFormat() == sw::FORMAT_X32B32G32R32UI);
+ return Transfer<RGB32toRGBX32>(buffer, input, rect);
+ case GL_INT:
+ ASSERT_OR_RETURN(internalformat == GL_RGB32I && getExternalFormat() == sw::FORMAT_X32B32G32R32I);
+ return Transfer<RGB32toRGBX32>(buffer, input, rect);
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_RG:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_FLOAT:
+ switch(internalformat)
+ {
+ case GL_RG32F: return Transfer<Bytes>(buffer, input, rect);
+ case GL_RG16F: return Transfer<RG32FtoRG16F>(buffer, input, rect);
+ default: UNREACHABLE(internalformat);
+ }
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_RG_INTEGER:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_RG8UI && getExternalFormat() == sw::FORMAT_G8R8UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_RG8I && getExternalFormat() == sw::FORMAT_G8R8I);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_SHORT:
+ ASSERT_OR_RETURN(internalformat == GL_RG16UI && getExternalFormat() == sw::FORMAT_G16R16UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_SHORT:
+ ASSERT_OR_RETURN(internalformat == GL_RG16I && getExternalFormat() == sw::FORMAT_G16R16I);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_INT:
+ ASSERT_OR_RETURN(internalformat == GL_RG32UI && getExternalFormat() == sw::FORMAT_G32R32UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_INT:
+ ASSERT_OR_RETURN(internalformat == GL_RG32I && getExternalFormat() == sw::FORMAT_G32R32I);
+ return Transfer<Bytes>(buffer, input, rect);
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_RED:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_FLOAT:
+ switch(internalformat)
+ {
+ case GL_R32F: return Transfer<Bytes>(buffer, input, rect);
+ case GL_R16F: return Transfer<R32FtoR16F>(buffer, input, rect);
+ default: UNREACHABLE(internalformat);
+ }
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_RED_INTEGER:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_R8UI && getExternalFormat() == sw::FORMAT_R8UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_BYTE:
+ ASSERT_OR_RETURN(internalformat == GL_R8I && getExternalFormat() == sw::FORMAT_R8I);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_SHORT:
+ ASSERT_OR_RETURN(internalformat == GL_R16UI && getExternalFormat() == sw::FORMAT_R16UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_SHORT:
+ ASSERT_OR_RETURN(internalformat == GL_R16I && getExternalFormat() == sw::FORMAT_R16I);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_UNSIGNED_INT:
+ ASSERT_OR_RETURN(internalformat == GL_R32UI && getExternalFormat() == sw::FORMAT_R32UI);
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_INT:
+ ASSERT_OR_RETURN(internalformat == GL_R32I && getExternalFormat() == sw::FORMAT_R32I);
+ return Transfer<Bytes>(buffer, input, rect);
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_DEPTH_COMPONENT:
+ switch(type)
+ {
+ case GL_UNSIGNED_SHORT: return Transfer<D16toD32F>(buffer, input, rect);
+ case GL_UNSIGNED_INT: return Transfer<D32toD32F>(buffer, input, rect);
+ case GL_FLOAT: return Transfer<D32FtoD32F_CLAMPED>(buffer, input, rect);
+ case GL_DEPTH_COMPONENT24: // Only valid for glRenderbufferStorage calls.
+ case GL_DEPTH_COMPONENT32_OES: // Only valid for glRenderbufferStorage calls.
+ default: UNREACHABLE(type);
+ }
+ case GL_DEPTH_STENCIL:
+ switch(type)
+ {
+ case GL_UNSIGNED_INT_24_8: return Transfer<D24X8toD32F>(buffer, input, rect);
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return Transfer<D32FX32toD32F>(buffer, input, rect);
+ default: UNREACHABLE(type);
+ }
+ case GL_LUMINANCE_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_FLOAT:
+ switch(internalformat)
+ {
+ case GL_LUMINANCE_ALPHA32F_EXT: return Transfer<Bytes>(buffer, input, rect);
+ case GL_LUMINANCE_ALPHA16F_EXT: return Transfer<RG32FtoRG16F>(buffer, input, rect);
+ default: UNREACHABLE(internalformat);
+ }
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ ASSERT_OR_RETURN(internalformat == GL_LUMINANCE_ALPHA16F_EXT);
+ return Transfer<Bytes>(buffer, input, rect);
+ default:
+ UNREACHABLE(type);
+ }
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return Transfer<Bytes>(buffer, input, rect);
+ case GL_FLOAT:
+ switch(internalformat)
+ {
+ case GL_LUMINANCE32F_EXT: return Transfer<Bytes>(buffer, input, rect);
+ case GL_LUMINANCE16F_EXT: return Transfer<R32FtoR16F>(buffer, input, rect);
+ case GL_ALPHA32F_EXT: return Transfer<Bytes>(buffer, input, rect);
+ case GL_ALPHA16F_EXT: return Transfer<R32FtoR16F>(buffer, input, rect);
+ default: UNREACHABLE(internalformat);
+ }
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ ASSERT_OR_RETURN(internalformat == GL_LUMINANCE16F_EXT || internalformat == GL_ALPHA16F_EXT);
+ return Transfer<Bytes>(buffer, input, rect);
+ default:
+ UNREACHABLE(type);
+ }
+ default:
+ UNREACHABLE(format);
}
}
- void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer)
+ void Image::loadStencilData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer)
{
- LoadImageData<D24>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+ Rectangle rect;
+ rect.bytes = gl::ComputePixelSize(format, type);
+ rect.width = width;
+ rect.height = height;
+ rect.depth = depth;
+ rect.inputPitch = inputPitch;
+ rect.inputHeight = inputHeight;
+ rect.destPitch = getStencilPitchB();
+ rect.destSlice = getStencilSliceB();
- unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, 0, 0, sw::PUBLIC));
-
- if(stencil)
+ switch(type)
{
- LoadImageData<S8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getStencilPitchB(), getHeight(), input, stencil);
-
- unlockStencil();
+ case GL_UNSIGNED_INT_24_8: return Transfer<X24S8toS8>(buffer, input, rect);
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: return Transfer<X56S8toS8>(buffer, input, rect);
+ default: UNREACHABLE(format);
}
}
- void Image::loadD32FS8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer)
+ void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
- LoadImageData<D32F>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+ GLsizei inputWidth = (unpackParameters.rowLength == 0) ? width : unpackParameters.rowLength;
+ GLsizei inputPitch = gl::ComputePitch(inputWidth, format, type, unpackParameters.alignment);
+ GLsizei inputHeight = (unpackParameters.imageHeight == 0) ? height : unpackParameters.imageHeight;
+ char *input = ((char*)pixels) + gl::ComputePackingOffset(format, type, inputWidth, inputHeight, unpackParameters);
- unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, 0, 0, sw::PUBLIC));
+ void *buffer = lock(xoffset, yoffset, zoffset, sw::LOCK_WRITEONLY);
- if(stencil)
+ if(buffer)
{
- LoadImageData<S24_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getStencilPitchB(), getHeight(), input, stencil);
+ loadImageData(width, height, depth, inputPitch, inputHeight, format, type, input, buffer);
+ }
+
+ unlock();
+
+ if(hasStencil())
+ {
+ unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(xoffset, yoffset, zoffset, sw::PUBLIC));
+
+ if(stencil)
+ {
+ loadStencilData(width, height, depth, inputPitch, inputHeight, format, type, input, stencil);
+ }
unlockStencil();
}
@@ -1722,20 +1637,22 @@
void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
{
- if(zoffset != 0 || depth != 1)
- {
- UNIMPLEMENTED(); // FIXME
- }
+ int inputPitch = gl::ComputeCompressedPitch(width, internalformat);
+ int inputSlice = imageSize / depth;
+ int rows = inputSlice / inputPitch;
- int inputPitch = ComputeCompressedPitch(width, format);
- int rows = imageSize / inputPitch;
- void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
+ void *buffer = lock(xoffset, yoffset, zoffset, sw::LOCK_WRITEONLY);
if(buffer)
{
- for(int i = 0; i < rows; i++)
+ for(int z = 0; z < depth; z++)
{
- memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
+ for(int y = 0; y < rows; y++)
+ {
+ GLbyte *dest = (GLbyte*)buffer + y * getPitch() + z * getSlice();
+ GLbyte *source = (GLbyte*)pixels + y * inputPitch + z * inputSlice;
+ memcpy(dest, source, inputPitch);
+ }
}
}
diff --git a/src/OpenGL/common/Image.hpp b/src/OpenGL/common/Image.hpp
index ecd6cd7..c6cc6a0 100644
--- a/src/OpenGL/common/Image.hpp
+++ b/src/OpenGL/common/Image.hpp
@@ -36,36 +36,50 @@
#define SW_YV12_BT709 0x48315659 // YCrCb 4:2:0 Planar, 16-byte aligned, BT.709 color space, studio swing
#define SW_YV12_JFIF 0x4A315659 // YCrCb 4:2:0 Planar, 16-byte aligned, BT.601 color space, full swing
-namespace egl
+namespace gl
{
-class Context;
+struct PixelStorageModes
+{
+ GLint rowLength = 0;
+ GLint skipRows = 0;
+ GLint skipPixels = 0;
+ GLint alignment = 4;
+ GLint imageHeight = 0;
+ GLint skipImages = 0;
+};
-sw::Format ConvertFormatType(GLenum format, GLenum type);
-sw::Format SelectInternalFormat(GLenum format, GLenum type);
+GLint GetSizedInternalFormat(GLint internalFormat, GLenum type);
+sw::Format ConvertReadFormatType(GLenum format, GLenum type);
+sw::Format SelectInternalFormat(GLint format);
+bool IsUnsizedInternalFormat(GLint internalformat);
+GLenum GetBaseInternalFormat(GLint internalformat);
GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
-size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, GLint skipImages, GLint skipRows, GLint skipPixels);
+size_t ComputePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, const PixelStorageModes &storageModes);
+
+}
+
+namespace egl
+{
class [[clang::lto_visibility_public]] Image : public sw::Surface, public gl::Object
{
protected:
// 2D texture image
- Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
- : sw::Surface(parentTexture->getResource(), width, height, 1, SelectInternalFormat(format, type), true, true),
- width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
- parentTexture(parentTexture)
+ Image(Texture *parentTexture, GLsizei width, GLsizei height, GLint internalformat)
+ : sw::Surface(parentTexture->getResource(), width, height, 1, 0, 1, gl::SelectInternalFormat(internalformat), true, true),
+ width(width), height(height), depth(1), internalformat(internalformat), parentTexture(parentTexture)
{
shared = false;
Object::addRef();
parentTexture->addRef();
}
- // 3D texture image
- Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type)
- : sw::Surface(parentTexture->getResource(), width, height, depth, SelectInternalFormat(format, type), true, true),
- width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(depth),
- parentTexture(parentTexture)
+ // 3D/Cube texture image
+ Image(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLint internalformat)
+ : sw::Surface(parentTexture->getResource(), width, height, depth, border, 1, gl::SelectInternalFormat(internalformat), true, true),
+ width(width), height(height), depth(depth), internalformat(internalformat), parentTexture(parentTexture)
{
shared = false;
Object::addRef();
@@ -73,20 +87,18 @@
}
// Native EGL image
- Image(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP)
- : sw::Surface(nullptr, width, height, 1, SelectInternalFormat(format, type), true, true, pitchP),
- width(width), height(height), format(format), type(type), internalFormat(SelectInternalFormat(format, type)), depth(1),
- parentTexture(nullptr)
+ Image(GLsizei width, GLsizei height, GLint internalformat, int pitchP)
+ : sw::Surface(nullptr, width, height, 1, 0, 1, gl::SelectInternalFormat(internalformat), true, true, pitchP),
+ width(width), height(height), depth(1), internalformat(internalformat), parentTexture(nullptr)
{
shared = true;
Object::addRef();
}
// Render target
- Image(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable)
- : sw::Surface(nullptr, width, height, multiSampleDepth, internalFormat, lockable, true),
- width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), depth(multiSampleDepth),
- parentTexture(nullptr)
+ Image(GLsizei width, GLsizei height, GLint internalformat, int multiSampleDepth, bool lockable)
+ : sw::Surface(nullptr, width, height, 1, 0, multiSampleDepth, gl::SelectInternalFormat(internalformat), lockable, true),
+ width(width), height(height), depth(1), internalformat(internalformat), parentTexture(nullptr)
{
shared = false;
Object::addRef();
@@ -94,16 +106,16 @@
public:
// 2D texture image
- static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
+ static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLint internalformat);
- // 3D texture image
- static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type);
+ // 3D/Cube texture image
+ static Image *create(Texture *parentTexture, GLsizei width, GLsizei height, GLsizei depth, int border, GLint internalformat);
// Native EGL image
- static Image *create(GLsizei width, GLsizei height, GLenum format, GLenum type, int pitchP);
+ static Image *create(GLsizei width, GLsizei height, GLint internalformat, int pitchP);
// Render target
- static Image *create(GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable);
+ static Image *create(GLsizei width, GLsizei height, GLint internalformat, int multiSampleDepth, bool lockable);
GLsizei getWidth() const
{
@@ -122,19 +134,9 @@
return depth;
}
- GLenum getFormat() const
+ GLint getFormat() const
{
- return format;
- }
-
- GLenum getType() const
- {
- return type;
- }
-
- sw::Format getInternalFormat() const
- {
- return internalFormat;
+ return internalformat;
}
bool isShared() const
@@ -147,9 +149,9 @@
shared = true;
}
- virtual void *lock(unsigned int left, unsigned int top, sw::Lock lock)
+ virtual void *lock(int x, int y, int z, sw::Lock lock)
{
- return lockExternal(left, top, 0, lock, sw::PUBLIC);
+ return lockExternal(x, y, z, lock, sw::PUBLIC);
}
unsigned int getPitch() const
@@ -157,6 +159,11 @@
return getExternalPitchB();
}
+ unsigned int getSlice() const
+ {
+ return getExternalSliceB();
+ }
+
virtual void unlock()
{
unlockExternal();
@@ -165,19 +172,7 @@
void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override = 0;
void unlockInternal() override = 0;
- struct UnpackInfo
- {
- UnpackInfo() : alignment(4), rowLength(0), imageHeight(0), skipPixels(0), skipRows(0), skipImages(0) {}
-
- GLint alignment;
- GLint rowLength;
- GLint imageHeight;
- GLint skipPixels;
- GLint skipRows;
- GLint skipImages;
- };
-
- void loadImageData(Context *context, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input);
+ void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
void release() override = 0;
@@ -194,10 +189,8 @@
protected:
const GLsizei width;
const GLsizei height;
- const GLenum format;
- const GLenum type;
- const sw::Format internalFormat;
const int depth;
+ const GLint internalformat;
bool shared; // Used as an EGLImage
@@ -205,8 +198,8 @@
~Image() override = 0;
- void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);
- void loadD32FS8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);
+ void loadImageData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer);
+ void loadStencilData(GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, GLenum format, GLenum type, const void *input, void *buffer);
};
#ifdef __ANDROID__
@@ -233,35 +226,12 @@
}
}
-inline GLenum GLPixelTypeFromAndroid(int halFormat)
-{
- switch(halFormat)
- {
- case HAL_PIXEL_FORMAT_RGBA_8888: return GL_UNSIGNED_BYTE;
-#if ANDROID_PLATFORM_SDK_VERSION > 16
- case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: return GL_UNSIGNED_BYTE;
-#endif
- case HAL_PIXEL_FORMAT_RGBX_8888: return GL_UNSIGNED_BYTE;
- case HAL_PIXEL_FORMAT_BGRA_8888: return GL_UNSIGNED_BYTE;
- case HAL_PIXEL_FORMAT_RGB_565: return GL_UNSIGNED_SHORT_5_6_5;
- case HAL_PIXEL_FORMAT_YV12: return GL_UNSIGNED_BYTE;
-#ifdef GRALLOC_MODULE_API_VERSION_0_2
- case HAL_PIXEL_FORMAT_YCbCr_420_888: return GL_UNSIGNED_BYTE;
-#endif
- case HAL_PIXEL_FORMAT_RGB_888: // Unsupported.
- default:
- ALOGE("Unsupported EGL image format %d", halFormat); ASSERT(false);
- return GL_NONE;
- }
-}
-
class AndroidNativeImage : public egl::Image
{
public:
explicit AndroidNativeImage(ANativeWindowBuffer *nativeBuffer)
: egl::Image(nativeBuffer->width, nativeBuffer->height,
GLPixelFormatFromAndroid(nativeBuffer->format),
- GLPixelTypeFromAndroid(nativeBuffer->format),
nativeBuffer->stride),
nativeBuffer(nativeBuffer)
{
@@ -320,10 +290,10 @@
sw::Surface::unlockInternal();
}
- void *lock(unsigned int left, unsigned int top, sw::Lock lock) override
+ void *lock(int x, int y, int z, sw::Lock lock) override
{
LOGLOCK("image=%p op=%s lock=%d", this, __FUNCTION__, lock);
- (void)sw::Surface::lockExternal(left, top, 0, lock, sw::PUBLIC);
+ (void)sw::Surface::lockExternal(x, y, z, lock, sw::PUBLIC);
return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
}
diff --git a/src/OpenGL/common/Surface.hpp b/src/OpenGL/common/Surface.hpp
index 50a9d00..493d676 100644
--- a/src/OpenGL/common/Surface.hpp
+++ b/src/OpenGL/common/Surface.hpp
@@ -40,8 +40,6 @@
virtual egl::Image *getRenderTarget() = 0;
virtual egl::Image *getDepthStencil() = 0;
- virtual sw::Format getInternalFormat() const = 0;
-
virtual EGLint getWidth() const = 0;
virtual EGLint getHeight() const = 0;
diff --git a/src/OpenGL/common/debug.h b/src/OpenGL/common/debug.h
index bbf7521..aadb535 100644
--- a/src/OpenGL/common/debug.h
+++ b/src/OpenGL/common/debug.h
@@ -56,19 +56,19 @@
// A macro asserting a condition and outputting failures to the debug log
#undef ASSERT
-#if !defined(NDEBUG)
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define ASSERT(expression) do { \
- if(!(expression)) \
+ if(!(expression)) { \
ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \
assert(expression); \
- } while(0)
+ } } while(0)
#else
#define ASSERT(expression) (void(0))
#endif
// A macro to indicate unimplemented functionality
#undef UNIMPLEMENTED
-#if !defined(NDEBUG)
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define UNIMPLEMENTED() do { \
FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \
assert(false); \
@@ -79,7 +79,7 @@
// A macro for code which is not expected to be reached under valid assumptions
#undef UNREACHABLE
-#if !defined(NDEBUG)
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define UNREACHABLE(value) do { \
ERR("\t! Unreachable case reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value); \
assert(false); \
@@ -88,6 +88,14 @@
#define UNREACHABLE(value) ERR("\t! Unreachable reached: %s(%d). %s: %d\n", __FUNCTION__, __LINE__, #value, value)
#endif
-#endif // __ANDROID__
+#endif // !__ANDROID__
+
+// A macro asserting a condition and outputting failures to the debug log, or return when in release mode.
+#undef ASSERT_OR_RETURN
+#define ASSERT_OR_RETURN(expression) do { \
+ if(!(expression)) { \
+ ASSERT(expression); \
+ return; \
+ } } while(0)
#endif // COMMON_DEBUG_H_
diff --git a/src/OpenGL/compiler/Android.mk b/src/OpenGL/compiler/Android.mk
index 4eb2349..6924e48 100644
--- a/src/OpenGL/compiler/Android.mk
+++ b/src/OpenGL/compiler/Android.mk
@@ -44,8 +44,8 @@
endif
COMMON_SRC_FILES := \
- preprocessor/Diagnostics.cpp \
- preprocessor/DirectiveHandler.cpp \
+ preprocessor/DiagnosticsBase.cpp \
+ preprocessor/DirectiveHandlerBase.cpp \
preprocessor/DirectiveParser.cpp \
preprocessor/ExpressionParser.cpp \
preprocessor/Input.cpp \
diff --git a/src/OpenGL/compiler/BUILD.gn b/src/OpenGL/compiler/BUILD.gn
index 3759f1c..ea72f32 100644
--- a/src/OpenGL/compiler/BUILD.gn
+++ b/src/OpenGL/compiler/BUILD.gn
@@ -13,6 +13,7 @@
# limitations under the License.
import("../../swiftshader.gni")
+import("//testing/libfuzzer/fuzzer_test.gni")
# Need a separate config to ensure the warnings are added to the end.
config("swiftshader_opengl_compiler_private_config") {
@@ -37,6 +38,10 @@
}
}
+config("swiftshader_translator_disable_pool_alloc") {
+ defines = [ "SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC" ]
+}
+
swiftshader_source_set("swiftshader_opengl_compiler") {
deps = [
"preprocessor:swiftshader_opengl_preprocessor",
@@ -67,7 +72,11 @@
"util.cpp",
]
- if (is_linux || is_mac) {
+ if (use_fuzzing_engine) {
+ all_dependent_configs = [ ":swiftshader_translator_disable_pool_alloc" ]
+ }
+
+ if (is_linux || is_mac || is_fuchsia) {
sources += [ "ossource_posix.cpp" ]
} else if (is_win) {
sources += [ "ossource_win.cpp" ]
diff --git a/src/OpenGL/compiler/BaseTypes.h b/src/OpenGL/compiler/BaseTypes.h
index 01f9948..67b465d 100644
--- a/src/OpenGL/compiler/BaseTypes.h
+++ b/src/OpenGL/compiler/BaseTypes.h
@@ -64,6 +64,7 @@
EbtSampler3D,
EbtSamplerCube,
EbtSampler2DArray,
+ EbtSampler2DRect, // Only valid if ARB_texture_rectangle exists.
EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists.
EbtISampler2D,
EbtISampler3D,
@@ -113,6 +114,7 @@
case EbtBool: return "bool";
case EbtSampler2D: return "sampler2D";
case EbtSamplerCube: return "samplerCube";
+ case EbtSampler2DRect: return "sampler2DRect";
case EbtSamplerExternalOES: return "samplerExternalOES";
case EbtSampler3D: return "sampler3D";
case EbtStruct: return "structure";
@@ -164,6 +166,7 @@
case EbtSampler2D:
case EbtSampler3D:
case EbtSamplerCube:
+ case EbtSampler2DRect:
case EbtSamplerExternalOES:
case EbtSampler2DArray:
case EbtSampler2DShadow:
@@ -187,6 +190,7 @@
case EbtSampler2DArray:
case EbtISampler2DArray:
case EbtUSampler2DArray:
+ case EbtSampler2DRect:
case EbtSamplerExternalOES:
case EbtSampler2DShadow:
case EbtSampler2DArrayShadow:
@@ -217,6 +221,7 @@
return true;
case EbtSampler2D:
case EbtSampler3D:
+ case EbtSampler2DRect:
case EbtSamplerExternalOES:
case EbtSampler2DArray:
case EbtISampler2D:
@@ -245,6 +250,7 @@
return true;
case EbtSampler2D:
case EbtSamplerCube:
+ case EbtSampler2DRect:
case EbtSamplerExternalOES:
case EbtSampler2DArray:
case EbtISampler2D:
@@ -276,6 +282,7 @@
case EbtSampler2D:
case EbtISampler2D:
case EbtUSampler2D:
+ case EbtSampler2DRect:
case EbtSamplerExternalOES:
case EbtSampler3D:
case EbtISampler3D:
@@ -312,6 +319,7 @@
case EbtSampler2D:
case EbtSampler3D:
case EbtSamplerCube:
+ case EbtSampler2DRect:
case EbtSamplerExternalOES:
case EbtSampler2DArray:
return false;
diff --git a/src/OpenGL/compiler/Compiler.cpp b/src/OpenGL/compiler/Compiler.cpp
index 7861acf..ae93385 100644
--- a/src/OpenGL/compiler/Compiler.cpp
+++ b/src/OpenGL/compiler/Compiler.cpp
@@ -227,7 +227,11 @@
else if(depth > maxCallStackDepth)
{
infoSink.info.prefix(EPrefixError);
- infoSink.info << "Function call stack too deep";
+ infoSink.info << "Function call stack too deep (depth was ";
+ infoSink.info << depth;
+ infoSink.info << " while maximum call stack depth is ";
+ infoSink.info << maxCallStackDepth;
+ infoSink.info << ")";
return false;
}
diff --git a/src/OpenGL/compiler/Compiler.h b/src/OpenGL/compiler/Compiler.h
index 8cdc755..89acc04 100644
--- a/src/OpenGL/compiler/Compiler.h
+++ b/src/OpenGL/compiler/Compiler.h
@@ -58,6 +58,7 @@
int OES_fragment_precision_high;
int OES_EGL_image_external;
int EXT_draw_buffers;
+ int ARB_texture_rectangle;
unsigned int MaxCallStackDepth;
};
@@ -66,6 +67,29 @@
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
+// Note: GL_ARB_texture_rectangle is part of gl2extchromium.h in the Chromium repo
+// GL_ARB_texture_rectangle
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
+
+#ifndef GL_SAMPLER_2D_RECT_ARB
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#endif
+
+#ifndef GL_TEXTURE_BINDING_RECTANGLE_ARB
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#endif
+
+#ifndef GL_TEXTURE_RECTANGLE_ARB
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#endif
+
+#ifndef GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
+
+#endif // GL_ARB_texture_rectangle
+
//
// The base class for the machine dependent compiler to derive from
// for managing object code from the compile.
diff --git a/src/OpenGL/compiler/Compiler.vcxproj b/src/OpenGL/compiler/Compiler.vcxproj
index c4f56bf..1360d93 100644
--- a/src/OpenGL/compiler/Compiler.vcxproj
+++ b/src/OpenGL/compiler/Compiler.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,41 +31,42 @@
<RootNamespace>compiler</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>Compiler</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -126,6 +127,8 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;4005;</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
+ <ErrorReporting>Queue</ErrorReporting>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -143,6 +146,8 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;4005;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
+ <ErrorReporting>Queue</ErrorReporting>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -159,6 +164,8 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;4005;</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
+ <ErrorReporting>Queue</ErrorReporting>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -175,6 +182,8 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;4005;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
+ <ErrorReporting>Queue</ErrorReporting>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
@@ -191,6 +200,8 @@
<OmitFramePointers>false</OmitFramePointers>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;4005;</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
+ <ErrorReporting>Queue</ErrorReporting>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
@@ -207,6 +218,8 @@
<OmitFramePointers>false</OmitFramePointers>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;4005;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
+ <ErrorReporting>Queue</ErrorReporting>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/src/OpenGL/compiler/Diagnostics.h b/src/OpenGL/compiler/Diagnostics.h
index 35983ac..43ee573 100644
--- a/src/OpenGL/compiler/Diagnostics.h
+++ b/src/OpenGL/compiler/Diagnostics.h
@@ -15,7 +15,7 @@
#ifndef COMPILER_DIAGNOSTICS_H_
#define COMPILER_DIAGNOSTICS_H_
-#include "preprocessor/Diagnostics.h"
+#include "preprocessor/DiagnosticsBase.h"
class TInfoSink;
diff --git a/src/OpenGL/compiler/DirectiveHandler.cpp b/src/OpenGL/compiler/DirectiveHandler.cpp
index 2391d35..ef61d47 100644
--- a/src/OpenGL/compiler/DirectiveHandler.cpp
+++ b/src/OpenGL/compiler/DirectiveHandler.cpp
@@ -54,7 +54,8 @@
void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
const std::string& name,
- const std::string& value)
+ const std::string& value,
+ bool stdgl)
{
static const std::string kSTDGL("STDGL");
static const std::string kOptimize("optimize");
@@ -63,7 +64,7 @@
static const std::string kOff("off");
bool invalidValue = false;
- if (name == kSTDGL)
+ if (stdgl || (name == kSTDGL))
{
// The STDGL pragma is used to reserve pragmas for use by future
// revisions of GLSL. Ignore it.
@@ -83,7 +84,7 @@
}
else
{
- mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name);
+ mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
return;
}
diff --git a/src/OpenGL/compiler/DirectiveHandler.h b/src/OpenGL/compiler/DirectiveHandler.h
index f77d1f9..0538c59 100644
--- a/src/OpenGL/compiler/DirectiveHandler.h
+++ b/src/OpenGL/compiler/DirectiveHandler.h
@@ -17,7 +17,7 @@
#include "ExtensionBehavior.h"
#include "Pragma.h"
-#include "preprocessor/DirectiveHandler.h"
+#include "preprocessor/DirectiveHandlerBase.h"
class TDiagnostics;
@@ -37,7 +37,8 @@
virtual void handlePragma(const pp::SourceLocation& loc,
const std::string& name,
- const std::string& value);
+ const std::string& value,
+ bool stdgl);
virtual void handleExtension(const pp::SourceLocation& loc,
const std::string& name,
diff --git a/src/OpenGL/compiler/Initialize.cpp b/src/OpenGL/compiler/Initialize.cpp
index c374531..23bc792 100644
--- a/src/OpenGL/compiler/Initialize.cpp
+++ b/src/OpenGL/compiler/Initialize.cpp
@@ -103,6 +103,7 @@
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, genUType, genUType);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, float1);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, genBType);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", genType, genType);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", float1, genType);
symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", genType, genType, genType);
@@ -242,6 +243,18 @@
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture3D", sampler3D, float3);
+ if(resources.ARB_texture_rectangle)
+ {
+ TType *sampler2DRect = new TType(EbtSampler2DRect);
+
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRect", sampler2DRect, float2);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float3);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", sampler2DRect, float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", sampler2DRect, float3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", sampler2DRect, float4);
+ }
+
if(resources.OES_EGL_image_external)
{
TType *samplerExternalOES = new TType(EbtSamplerExternalOES);
@@ -427,10 +440,10 @@
fields->push_back(diff);
TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
- symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters);
+ symbolTable.insert(COMMON_BUILTINS, depthRangeParameters);
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
depthRange->setQualifier(EvqUniform);
- symbolTable.insert(COMMON_BUILTINS, *depthRange);
+ symbolTable.insert(COMMON_BUILTINS, depthRange);
//
// Implementation dependent built-in constants.
@@ -441,8 +454,8 @@
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", resources.MaxTextureImageUnits);
symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors);
+ symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers);
symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors);
- symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", resources.MaxFragmentInputVectors);
symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", resources.MinProgramTexelOffset);
@@ -460,18 +473,18 @@
switch(shaderType)
{
case GL_FRAGMENT_SHADER:
- symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
- symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
- symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
- symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
- symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
- symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
+ symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
break;
case GL_VERTEX_SHADER:
- symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
- symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
- symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
- symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
+ symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
+ symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1)));
break;
default: assert(false && "Language not supported");
}
@@ -484,7 +497,7 @@
// Set up gl_FragData. The array size.
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
fragData.setArraySize(resources.MaxDrawBuffers);
- symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData"), fragData));
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
}
break;
default: break;
@@ -502,4 +515,6 @@
extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
if(resources.EXT_draw_buffers)
extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
+ if(resources.ARB_texture_rectangle)
+ extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
}
diff --git a/src/OpenGL/compiler/Intermediate.cpp b/src/OpenGL/compiler/Intermediate.cpp
index a6b1b82..fbcb16b 100644
--- a/src/OpenGL/compiler/Intermediate.cpp
+++ b/src/OpenGL/compiler/Intermediate.cpp
@@ -402,7 +402,10 @@
node->setLeft(left);
node->setRight(right);
if (!node->promote(infoSink))
+ {
+ delete node;
return 0;
+ }
//
// See if we can fold constants.
@@ -1775,10 +1778,12 @@
//
TIntermConstantUnion *newNode = 0;
ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
+ TType type = getType();
+ TBasicType basicType = type.getBasicType();
for (size_t i = 0; i < objectSize; i++) {
switch(op) {
case EOpNegative:
- switch (getType().getBasicType()) {
+ switch (basicType) {
case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
case EbtInt: tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
default:
@@ -1787,7 +1792,7 @@
}
break;
case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
- switch (getType().getBasicType()) {
+ switch (basicType) {
case EbtBool: tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1795,7 +1800,7 @@
}
break;
case EOpBitwiseNot:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtInt: tempConstArray[i].setIConst(~unionArray[i].getIConst()); break;
case EbtUInt: tempConstArray[i].setUConst(~unionArray[i].getUConst()); break;
default:
@@ -1804,7 +1809,7 @@
}
break;
case EOpRadians:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(unionArray[i].getFConst() * 1.74532925e-2f); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1812,7 +1817,7 @@
}
break;
case EOpDegrees:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(unionArray[i].getFConst() * 5.72957795e+1f); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1820,7 +1825,7 @@
}
break;
case EOpSin:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(sinf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1828,7 +1833,7 @@
}
break;
case EOpCos:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(cosf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1836,7 +1841,7 @@
}
break;
case EOpTan:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(tanf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1844,7 +1849,7 @@
}
break;
case EOpAsin:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(asinf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1852,7 +1857,7 @@
}
break;
case EOpAcos:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(acosf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1860,7 +1865,7 @@
}
break;
case EOpAtan:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(atanf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1868,7 +1873,7 @@
}
break;
case EOpSinh:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(sinhf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1876,7 +1881,7 @@
}
break;
case EOpCosh:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(coshf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1884,7 +1889,7 @@
}
break;
case EOpTanh:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(tanhf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1892,7 +1897,7 @@
}
break;
case EOpAsinh:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(asinhf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1900,7 +1905,7 @@
}
break;
case EOpAcosh:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(acoshf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1908,7 +1913,7 @@
}
break;
case EOpAtanh:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(atanhf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1916,7 +1921,7 @@
}
break;
case EOpLog:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(logf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1924,7 +1929,7 @@
}
break;
case EOpLog2:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(sw::log2(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1932,7 +1937,7 @@
}
break;
case EOpExp:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(expf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1940,7 +1945,7 @@
}
break;
case EOpExp2:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(exp2f(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1948,7 +1953,7 @@
}
break;
case EOpSqrt:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(sqrtf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1956,18 +1961,63 @@
}
break;
case EOpInverseSqrt:
- switch(getType().getBasicType()) {
+ switch(basicType) {
case EbtFloat: tempConstArray[i].setFConst(1.0f / sqrtf(unionArray[i].getFConst())); break;
default:
infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
return 0;
}
break;
+ case EOpFloatBitsToInt:
+ switch(basicType) {
+ case EbtFloat:
+ tempConstArray[i].setIConst(sw::bitCast<int>(unionArray[i].getFConst()));
+ type.setBasicType(EbtInt);
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+ return 0;
+ }
+ break;
+ break;
+ case EOpFloatBitsToUint:
+ switch(basicType) {
+ case EbtFloat:
+ tempConstArray[i].setUConst(sw::bitCast<unsigned int>(unionArray[i].getFConst()));
+ type.setBasicType(EbtUInt);
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+ return 0;
+ }
+ break;
+ case EOpIntBitsToFloat:
+ switch(basicType) {
+ case EbtInt:
+ tempConstArray[i].setFConst(sw::bitCast<float>(unionArray[i].getIConst()));
+ type.setBasicType(EbtFloat);
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+ return 0;
+ }
+ break;
+ case EOpUintBitsToFloat:
+ switch(basicType) {
+ case EbtUInt:
+ tempConstArray[i].setFConst(sw::bitCast<float>(unionArray[i].getUConst()));
+ type.setBasicType(EbtFloat);
+ break;
+ default:
+ infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+ return 0;
+ }
+ break;
default:
return 0;
}
}
- newNode = new TIntermConstantUnion(tempConstArray, getType());
+ newNode = new TIntermConstantUnion(tempConstArray, type);
newNode->setLine(getLine());
return newNode;
}
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 1c70f6c..b3385c2 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -26,6 +26,185 @@
#include <stdlib.h>
+namespace
+{
+ GLenum glVariableType(const TType &type)
+ {
+ switch(type.getBasicType())
+ {
+ case EbtFloat:
+ if(type.isScalar())
+ {
+ return GL_FLOAT;
+ }
+ else if(type.isVector())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2: return GL_FLOAT_VEC2;
+ case 3: return GL_FLOAT_VEC3;
+ case 4: return GL_FLOAT_VEC4;
+ default: UNREACHABLE(type.getNominalSize());
+ }
+ }
+ else if(type.isMatrix())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2:
+ switch(type.getSecondarySize())
+ {
+ case 2: return GL_FLOAT_MAT2;
+ case 3: return GL_FLOAT_MAT2x3;
+ case 4: return GL_FLOAT_MAT2x4;
+ default: UNREACHABLE(type.getSecondarySize());
+ }
+ case 3:
+ switch(type.getSecondarySize())
+ {
+ case 2: return GL_FLOAT_MAT3x2;
+ case 3: return GL_FLOAT_MAT3;
+ case 4: return GL_FLOAT_MAT3x4;
+ default: UNREACHABLE(type.getSecondarySize());
+ }
+ case 4:
+ switch(type.getSecondarySize())
+ {
+ case 2: return GL_FLOAT_MAT4x2;
+ case 3: return GL_FLOAT_MAT4x3;
+ case 4: return GL_FLOAT_MAT4;
+ default: UNREACHABLE(type.getSecondarySize());
+ }
+ default: UNREACHABLE(type.getNominalSize());
+ }
+ }
+ else UNREACHABLE(0);
+ break;
+ case EbtInt:
+ if(type.isScalar())
+ {
+ return GL_INT;
+ }
+ else if(type.isVector())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2: return GL_INT_VEC2;
+ case 3: return GL_INT_VEC3;
+ case 4: return GL_INT_VEC4;
+ default: UNREACHABLE(type.getNominalSize());
+ }
+ }
+ else UNREACHABLE(0);
+ break;
+ case EbtUInt:
+ if(type.isScalar())
+ {
+ return GL_UNSIGNED_INT;
+ }
+ else if(type.isVector())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2: return GL_UNSIGNED_INT_VEC2;
+ case 3: return GL_UNSIGNED_INT_VEC3;
+ case 4: return GL_UNSIGNED_INT_VEC4;
+ default: UNREACHABLE(type.getNominalSize());
+ }
+ }
+ else UNREACHABLE(0);
+ break;
+ case EbtBool:
+ if(type.isScalar())
+ {
+ return GL_BOOL;
+ }
+ else if(type.isVector())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2: return GL_BOOL_VEC2;
+ case 3: return GL_BOOL_VEC3;
+ case 4: return GL_BOOL_VEC4;
+ default: UNREACHABLE(type.getNominalSize());
+ }
+ }
+ else UNREACHABLE(0);
+ break;
+ case EbtSampler2D:
+ return GL_SAMPLER_2D;
+ case EbtISampler2D:
+ return GL_INT_SAMPLER_2D;
+ case EbtUSampler2D:
+ return GL_UNSIGNED_INT_SAMPLER_2D;
+ case EbtSamplerCube:
+ return GL_SAMPLER_CUBE;
+ case EbtSampler2DRect:
+ return GL_SAMPLER_2D_RECT_ARB;
+ case EbtISamplerCube:
+ return GL_INT_SAMPLER_CUBE;
+ case EbtUSamplerCube:
+ return GL_UNSIGNED_INT_SAMPLER_CUBE;
+ case EbtSamplerExternalOES:
+ return GL_SAMPLER_EXTERNAL_OES;
+ case EbtSampler3D:
+ return GL_SAMPLER_3D_OES;
+ case EbtISampler3D:
+ return GL_INT_SAMPLER_3D;
+ case EbtUSampler3D:
+ return GL_UNSIGNED_INT_SAMPLER_3D;
+ case EbtSampler2DArray:
+ return GL_SAMPLER_2D_ARRAY;
+ case EbtISampler2DArray:
+ return GL_INT_SAMPLER_2D_ARRAY;
+ case EbtUSampler2DArray:
+ return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
+ case EbtSampler2DShadow:
+ return GL_SAMPLER_2D_SHADOW;
+ case EbtSamplerCubeShadow:
+ return GL_SAMPLER_CUBE_SHADOW;
+ case EbtSampler2DArrayShadow:
+ return GL_SAMPLER_2D_ARRAY_SHADOW;
+ default:
+ UNREACHABLE(type.getBasicType());
+ break;
+ }
+
+ return GL_NONE;
+ }
+
+ GLenum glVariablePrecision(const TType &type)
+ {
+ if(type.getBasicType() == EbtFloat)
+ {
+ switch(type.getPrecision())
+ {
+ case EbpHigh: return GL_HIGH_FLOAT;
+ case EbpMedium: return GL_MEDIUM_FLOAT;
+ case EbpLow: return GL_LOW_FLOAT;
+ case EbpUndefined:
+ // Should be defined as the default precision by the parser
+ default: UNREACHABLE(type.getPrecision());
+ }
+ }
+ else if(type.getBasicType() == EbtInt)
+ {
+ switch(type.getPrecision())
+ {
+ case EbpHigh: return GL_HIGH_INT;
+ case EbpMedium: return GL_MEDIUM_INT;
+ case EbpLow: return GL_LOW_INT;
+ case EbpUndefined:
+ // Should be defined as the default precision by the parser
+ default: UNREACHABLE(type.getPrecision());
+ }
+ }
+
+ // Other types (boolean, sampler) don't have a precision
+ return GL_NONE;
+ }
+}
+
namespace glsl
{
// Integer to TString conversion
@@ -81,8 +260,21 @@
ConstantUnion constants[4];
};
- Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo) :
- type(type), precision(precision), name(name), arraySize(arraySize), registerIndex(registerIndex), blockId(blockId), blockInfo(blockMemberInfo)
+ ShaderVariable::ShaderVariable(const TType& type, const std::string& name, int registerIndex) :
+ type(type.isStruct() ? GL_NONE : glVariableType(type)), precision(glVariablePrecision(type)),
+ name(name), arraySize(type.getArraySize()), registerIndex(registerIndex)
+ {
+ if(type.isStruct())
+ {
+ for(const auto& field : type.getStruct()->fields())
+ {
+ fields.push_back(ShaderVariable(*(field->type()), field->name().c_str(), -1));
+ }
+ }
+ }
+
+ Uniform::Uniform(const TType& type, const std::string &name, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo) :
+ ShaderVariable(type, name, registerIndex), blockId(blockId), blockInfo(blockMemberInfo)
{
}
@@ -93,8 +285,8 @@
{
}
- BlockLayoutEncoder::BlockLayoutEncoder(bool rowMajor)
- : mCurrentOffset(0), isRowMajor(rowMajor)
+ BlockLayoutEncoder::BlockLayoutEncoder()
+ : mCurrentOffset(0)
{
}
@@ -103,6 +295,7 @@
int arrayStride;
int matrixStride;
+ bool isRowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
getBlockLayoutInfo(type, type.getArraySize(), isRowMajor, &arrayStride, &matrixStride);
const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * BytesPerComponent),
@@ -132,7 +325,7 @@
mCurrentOffset = sw::align(mCurrentOffset, ComponentsPerRegister);
}
- Std140BlockEncoder::Std140BlockEncoder(bool rowMajor) : BlockLayoutEncoder(rowMajor)
+ Std140BlockEncoder::Std140BlockEncoder() : BlockLayoutEncoder()
{
}
@@ -216,23 +409,23 @@
sw::PixelShader *Shader::getPixelShader() const
{
- return 0;
+ return nullptr;
}
sw::VertexShader *Shader::getVertexShader() const
{
- return 0;
+ return nullptr;
}
OutputASM::TextureFunction::TextureFunction(const TString& nodeName) : method(IMPLICIT), proj(false), offset(false)
{
TString name = TFunction::unmangleName(nodeName);
- if(name == "texture2D" || name == "textureCube" || name == "texture" || name == "texture3D")
+ if(name == "texture2D" || name == "textureCube" || name == "texture" || name == "texture3D" || name == "texture2DRect")
{
method = IMPLICIT;
}
- else if(name == "texture2DProj" || name == "textureProj")
+ else if(name == "texture2DProj" || name == "textureProj" || name == "texture2DRectProj")
{
method = IMPLICIT;
proj = true;
@@ -306,9 +499,9 @@
OutputASM::OutputASM(TParseContext &context, Shader *shaderObject) : TIntermTraverser(true, true, true), shaderObject(shaderObject), mContext(context)
{
- shader = 0;
- pixelShader = 0;
- vertexShader = 0;
+ shader = nullptr;
+ pixelShader = nullptr;
+ vertexShader = nullptr;
if(shaderObject)
{
@@ -317,9 +510,9 @@
vertexShader = shaderObject->getVertexShader();
}
- functionArray.push_back(Function(0, "main(", 0, 0));
+ functionArray.push_back(Function(0, "main(", nullptr, nullptr));
currentFunction = 0;
- outputQualifier = EvqOutput; // Set outputQualifier to any value other than EvqFragColor or EvqFragData
+ outputQualifier = EvqOutput; // Initialize outputQualifier to any value other than EvqFragColor or EvqFragData
}
OutputASM::~OutputASM()
@@ -465,14 +658,26 @@
void OutputASM::visitSymbol(TIntermSymbol *symbol)
{
- // Vertex varyings don't have to be actively used to successfully link
- // against pixel shaders that use them. So make sure they're declared.
- if(symbol->getQualifier() == EvqVaryingOut || symbol->getQualifier() == EvqInvariantVaryingOut || symbol->getQualifier() == EvqVertexOut)
+ // The type of vertex outputs and fragment inputs with the same name must match (validated at link time),
+ // so declare them but don't assign a register index yet (one will be assigned when referenced in reachable code).
+ switch(symbol->getQualifier())
{
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqInvariantVaryingIn:
+ case EvqInvariantVaryingOut:
+ case EvqVertexOut:
+ case EvqFragmentIn:
if(symbol->getBasicType() != EbtInvariant) // Typeless declarations are not new varyings
{
declareVarying(symbol, -1);
}
+ break;
+ case EvqFragmentOut:
+ declareFragmentOutput(symbol);
+ break;
+ default:
+ break;
}
TInterfaceBlock* block = symbol->getType().getInterfaceBlock();
@@ -507,32 +712,41 @@
switch(node->getOp())
{
case EOpAssign:
- if(visit == PostVisit)
- {
- assignLvalue(left, right);
- copy(result, right);
- }
- break;
+ assert(visit == PreVisit);
+ right->traverse(this);
+ assignLvalue(left, right);
+ copy(result, right);
+ return false;
case EOpInitialize:
- if(visit == PostVisit)
+ assert(visit == PreVisit);
+ // Constant arrays go into the constant register file.
+ if(leftType.getQualifier() == EvqConstExpr && leftType.isArray() && leftType.getArraySize() > 1)
{
+ for(int i = 0; i < left->totalRegisterCount(); i++)
+ {
+ emit(sw::Shader::OPCODE_DEF, left, i, right, i);
+ }
+ }
+ else
+ {
+ right->traverse(this);
copy(left, right);
}
- break;
+ return false;
case EOpMatrixTimesScalarAssign:
- if(visit == PostVisit)
+ assert(visit == PreVisit);
+ right->traverse(this);
+ for(int i = 0; i < leftType.getNominalSize(); i++)
{
- for(int i = 0; i < leftType.getNominalSize(); i++)
- {
- emit(sw::Shader::OPCODE_MUL, result, i, left, i, right);
- }
-
- assignLvalue(left, result);
+ emit(sw::Shader::OPCODE_MUL, result, i, left, i, right);
}
- break;
+
+ assignLvalue(left, result);
+ return false;
case EOpVectorTimesMatrixAssign:
- if(visit == PostVisit)
+ assert(visit == PreVisit);
{
+ right->traverse(this);
int size = leftType.getNominalSize();
for(int i = 0; i < size; i++)
@@ -543,10 +757,11 @@
assignLvalue(left, result);
}
- break;
+ return false;
case EOpMatrixTimesMatrixAssign:
- if(visit == PostVisit)
+ assert(visit == PreVisit);
{
+ right->traverse(this);
int dim = leftType.getNominalSize();
for(int i = 0; i < dim; i++)
@@ -563,94 +778,14 @@
assignLvalue(left, result);
}
- break;
+ return false;
case EOpIndexDirect:
- if(visit == PostVisit)
- {
- int index = right->getAsConstantUnion()->getIConst(0);
-
- if(result->isMatrix() || result->isStruct() || result->isInterfaceBlock())
- {
- ASSERT(left->isArray());
- copy(result, left, index * left->elementRegisterCount());
- }
- else if(result->isRegister())
- {
- int srcIndex = 0;
- if(left->isRegister())
- {
- srcIndex = 0;
- }
- else if(left->isArray())
- {
- srcIndex = index * left->elementRegisterCount();
- }
- else if(left->isMatrix())
- {
- ASSERT(index < left->getNominalSize()); // FIXME: Report semantic error
- srcIndex = index;
- }
- else UNREACHABLE(0);
-
- Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, 0, left, srcIndex);
-
- if(left->isRegister())
- {
- mov->src[0].swizzle = index;
- }
- }
- else UNREACHABLE(0);
- }
- break;
case EOpIndexIndirect:
- if(visit == PostVisit)
- {
- if(left->isArray() || left->isMatrix())
- {
- for(int index = 0; index < result->totalRegisterCount(); index++)
- {
- Instruction *mov = emit(sw::Shader::OPCODE_MOV, result, index, left, index);
- mov->dst.mask = writeMask(result, index);
-
- if(left->totalRegisterCount() > 1)
- {
- sw::Shader::SourceParameter relativeRegister;
- argument(relativeRegister, right);
-
- mov->src[0].rel.type = relativeRegister.type;
- mov->src[0].rel.index = relativeRegister.index;
- mov->src[0].rel.scale = result->totalRegisterCount();
- mov->src[0].rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
- }
- }
- }
- else if(left->isRegister())
- {
- emit(sw::Shader::OPCODE_EXTRACT, result, left, right);
- }
- else UNREACHABLE(0);
- }
- break;
case EOpIndexDirectStruct:
case EOpIndexDirectInterfaceBlock:
- if(visit == PostVisit)
- {
- ASSERT(leftType.isStruct() || (leftType.isInterfaceBlock()));
-
- const TFieldList& fields = (node->getOp() == EOpIndexDirectStruct) ?
- leftType.getStruct()->fields() :
- leftType.getInterfaceBlock()->fields();
- int index = right->getAsConstantUnion()->getIConst(0);
- int fieldOffset = 0;
-
- for(int i = 0; i < index; i++)
- {
- fieldOffset += fields[i]->type()->totalRegisterCount();
- }
-
- copy(result, left, fieldOffset);
- }
- break;
+ assert(visit == PreVisit);
+ evaluateRvalue(node);
+ return false;
case EOpVectorSwizzle:
if(visit == PostVisit)
{
@@ -1233,6 +1368,7 @@
else
{
const TextureFunction textureFunction(node->getName());
+ TIntermTyped *s = arg[0]->getAsTyped();
TIntermTyped *t = arg[1]->getAsTyped();
Temporary coord(this);
@@ -1245,73 +1381,88 @@
Instruction *mul = emit(sw::Shader::OPCODE_MUL, &coord, arg[1], &coord);
mul->dst.mask = 0x7;
+
+ if(IsShadowSampler(s->getBasicType()))
+ {
+ ASSERT(s->getBasicType() == EbtSampler2DShadow);
+ Instruction *mov = emit(sw::Shader::OPCODE_MOV, &coord, &coord);
+ mov->src[0].swizzle = 0xA4;
+ }
}
else
{
- emit(sw::Shader::OPCODE_MOV, &coord, arg[1]);
+ Instruction *mov = emit(sw::Shader::OPCODE_MOV, &coord, arg[1]);
+
+ if(IsShadowSampler(s->getBasicType()) && t->getNominalSize() == 3)
+ {
+ ASSERT(s->getBasicType() == EbtSampler2DShadow);
+ mov->src[0].swizzle = 0xA4;
+ }
}
switch(textureFunction.method)
{
case TextureFunction::IMPLICIT:
+ if(!textureFunction.offset)
{
- TIntermNode* offset = textureFunction.offset ? arg[2] : 0;
-
- if(argumentCount == 2 || (textureFunction.offset && argumentCount == 3))
+ if(argumentCount == 2)
{
- emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
- result, &coord, arg[0], offset);
+ emit(sw::Shader::OPCODE_TEX, result, &coord, s);
}
- else if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4)) // bias
+ else if(argumentCount == 3) // Bias
{
- Instruction *bias = emit(sw::Shader::OPCODE_MOV, &coord, arg[textureFunction.offset ? 3 : 2]);
- bias->dst.mask = 0x8;
-
- Instruction *tex = emit(textureFunction.offset ? sw::Shader::OPCODE_TEXOFFSET : sw::Shader::OPCODE_TEX,
- result, &coord, arg[0], offset); // FIXME: Implement an efficient TEXLDB instruction
- tex->bias = true;
+ emit(sw::Shader::OPCODE_TEXBIAS, result, &coord, s, arg[2]);
+ }
+ else UNREACHABLE(argumentCount);
+ }
+ else // Offset
+ {
+ if(argumentCount == 3)
+ {
+ emit(sw::Shader::OPCODE_TEXOFFSET, result, &coord, s, arg[2]);
+ }
+ else if(argumentCount == 4) // Bias
+ {
+ emit(sw::Shader::OPCODE_TEXOFFSETBIAS, result, &coord, s, arg[2], arg[3]);
}
else UNREACHABLE(argumentCount);
}
break;
case TextureFunction::LOD:
+ if(!textureFunction.offset && argumentCount == 3)
{
- Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]);
- lod->dst.mask = 0x8;
-
- emit(textureFunction.offset ? sw::Shader::OPCODE_TEXLDLOFFSET : sw::Shader::OPCODE_TEXLDL,
- result, &coord, arg[0], textureFunction.offset ? arg[3] : nullptr);
+ emit(sw::Shader::OPCODE_TEXLOD, result, &coord, s, arg[2]);
}
+ else if(argumentCount == 4) // Offset
+ {
+ emit(sw::Shader::OPCODE_TEXLODOFFSET, result, &coord, s, arg[3], arg[2]);
+ }
+ else UNREACHABLE(argumentCount);
break;
case TextureFunction::FETCH:
+ if(!textureFunction.offset && argumentCount == 3)
{
- if(argumentCount == 3 || (textureFunction.offset && argumentCount == 4))
- {
- Instruction *lod = emit(sw::Shader::OPCODE_MOV, &coord, arg[2]);
- lod->dst.mask = 0x8;
-
- TIntermNode *offset = textureFunction.offset ? arg[3] : nullptr;
-
- emit(textureFunction.offset ? sw::Shader::OPCODE_TEXELFETCHOFFSET : sw::Shader::OPCODE_TEXELFETCH,
- result, &coord, arg[0], offset);
- }
- else UNREACHABLE(argumentCount);
+ emit(sw::Shader::OPCODE_TEXELFETCH, result, &coord, s, arg[2]);
}
+ else if(argumentCount == 4) // Offset
+ {
+ emit(sw::Shader::OPCODE_TEXELFETCHOFFSET, result, &coord, s, arg[3], arg[2]);
+ }
+ else UNREACHABLE(argumentCount);
break;
case TextureFunction::GRAD:
+ if(!textureFunction.offset && argumentCount == 4)
{
- if(argumentCount == 4 || (textureFunction.offset && argumentCount == 5))
- {
- TIntermNode *offset = textureFunction.offset ? arg[4] : nullptr;
-
- emit(textureFunction.offset ? sw::Shader::OPCODE_TEXGRADOFFSET : sw::Shader::OPCODE_TEXGRAD,
- result, &coord, arg[0], arg[2], arg[3], offset);
- }
- else UNREACHABLE(argumentCount);
+ emit(sw::Shader::OPCODE_TEXGRAD, result, &coord, s, arg[2], arg[3]);
}
+ else if(argumentCount == 5) // Offset
+ {
+ emit(sw::Shader::OPCODE_TEXGRADOFFSET, result, &coord, s, arg[2], arg[3], arg[4]);
+ }
+ else UNREACHABLE(argumentCount);
break;
case TextureFunction::SIZE:
- emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], arg[0]);
+ emit(sw::Shader::OPCODE_TEXSIZE, result, arg[1], s);
break;
default:
UNREACHABLE(textureFunction.method);
@@ -1357,6 +1508,23 @@
component += size;
}
+ else if(!result->isMatrix()) // Construct a non matrix from a matrix
+ {
+ Instruction *mov = emitCast(result, arrayIndex, argi, 0);
+ mov->dst.mask = (0xF << swizzle) & 0xF;
+ mov->src[0].swizzle = readSwizzle(argi, size) << (swizzle * 2);
+
+ // At most one more instruction when constructing a vec3 from a mat2 or a vec4 from a mat2/mat3
+ if(result->getNominalSize() > size)
+ {
+ Instruction *mov = emitCast(result, arrayIndex, argi, 1);
+ mov->dst.mask = (0xF << (swizzle + size)) & 0xF;
+ // mat2: xxxy (0x40), mat3: xxxx (0x00)
+ mov->src[0].swizzle = ((size == 2) ? 0x40 : 0x00) << (swizzle * 2);
+ }
+
+ component += size;
+ }
else // Matrix
{
int column = 0;
@@ -1498,7 +1666,19 @@
emit(getOpcode(sw::Shader::OPCODE_MIN, result), result, result, arg[2]);
}
break;
- case EOpMix: if(visit == PostVisit) emit(sw::Shader::OPCODE_LRP, result, arg[2], arg[1], arg[0]); break;
+ case EOpMix:
+ if(visit == PostVisit)
+ {
+ if(arg[2]->getAsTyped()->getBasicType() == EbtBool)
+ {
+ emit(sw::Shader::OPCODE_SELECT, result, arg[2], arg[1], arg[0]);
+ }
+ else
+ {
+ emit(sw::Shader::OPCODE_LRP, result, arg[2], arg[1], arg[0]);
+ }
+ }
+ break;
case EOpStep: if(visit == PostVisit) emit(sw::Shader::OPCODE_STEP, result, arg[0], arg[1]); break;
case EOpSmoothStep: if(visit == PostVisit) emit(sw::Shader::OPCODE_SMOOTH, result, arg[0], arg[1], arg[2]); break;
case EOpDistance: if(visit == PostVisit) emit(sw::Shader::OPCODE_DIST(dim(arg[0])), result, arg[0], arg[1]); break;
@@ -1820,10 +2000,16 @@
emit(sw::Shader::OPCODE_IF, 0, &result);
nbCases++;
+ // Emit the code for this case and all subsequent cases until we hit a break statement.
+ // TODO: This can repeat a lot of code for switches with many fall-through cases.
for(++caseIt; caseIt != sequence.end(); ++caseIt)
{
(*caseIt)->traverse(this);
- if((*caseIt)->getAsBranchNode()) // Kill, Break, Continue or Return
+
+ // Stop if we encounter an unconditional branch (break, continue, return, or kill).
+ // TODO: This doesn't work if the statement is at a deeper scope level (e.g. {break;}).
+ // Note that this eliminates useless operations but shouldn't affect correctness.
+ if((*caseIt)->getAsBranchNode())
{
break;
}
@@ -1872,17 +2058,20 @@
if(dst)
{
- instruction->dst.type = registerType(dst);
- instruction->dst.index = registerIndex(dst) + dstIndex;
- instruction->dst.mask = writeMask(dst);
- instruction->dst.integer = (dst->getBasicType() == EbtInt);
+ destination(instruction->dst, dst, dstIndex);
}
- argument(instruction->src[0], src0, index0);
- argument(instruction->src[1], src1, index1);
- argument(instruction->src[2], src2, index2);
- argument(instruction->src[3], src3, index3);
- argument(instruction->src[4], src4, index4);
+ if(src0)
+ {
+ TIntermTyped* src = src0->getAsTyped();
+ instruction->dst.partialPrecision = src && (src->getPrecision() <= EbpLow);
+ }
+
+ source(instruction->src[0], src0, index0);
+ source(instruction->src[1], src1, index1);
+ source(instruction->src[2], src2, index2);
+ source(instruction->src[3], src3, index3);
+ source(instruction->src[4], src4, index4);
shader->append(instruction);
@@ -1997,9 +2186,9 @@
const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();
int elements = 0;
- for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
+ for(const auto &field : fields)
{
- const TType &fieldType = *((*field)->type());
+ const TType &fieldType = *(field->type());
if(fieldType.totalRegisterCount() <= registers)
{
@@ -2049,9 +2238,9 @@
const TFieldList& fields = type.getStruct() ? type.getStruct()->fields() : type.getInterfaceBlock()->fields();
int elements = 0;
- for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
+ for(const auto &field : fields)
{
- const TType &fieldType = *((*field)->type());
+ const TType &fieldType = *(field->type());
if(fieldType.totalRegisterCount() <= registers)
{
@@ -2156,7 +2345,7 @@
return argumentInfo;
}
- void OutputASM::argument(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index)
+ void OutputASM::source(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index)
{
if(argument)
{
@@ -2187,7 +2376,7 @@
arg = &unpackedUniform;
index = 0;
}
- else if((srcBlock->matrixPacking() == EmpRowMajor) && memberType.isMatrix())
+ else if((memberType.getLayoutQualifier().matrixPacking == EmpRowMajor) && memberType.isMatrix())
{
int numCols = memberType.getNominalSize();
int numRows = memberType.getSecondarySize();
@@ -2266,12 +2455,18 @@
}
}
+ void OutputASM::destination(sw::Shader::DestinationParameter ¶meter, TIntermTyped *arg, int index)
+ {
+ parameter.type = registerType(arg);
+ parameter.index = registerIndex(arg) + index;
+ parameter.mask = writeMask(arg, index);
+ }
+
void OutputASM::copy(TIntermTyped *dst, TIntermNode *src, int offset)
{
for(int index = 0; index < dst->totalRegisterCount(); index++)
{
Instruction *mov = emit(sw::Shader::OPCODE_MOV, dst, index, src, offset + index);
- mov->dst.mask = writeMask(dst, index);
}
}
@@ -2290,9 +2485,8 @@
void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)
{
- if(src &&
- ((src->isVector() && (!dst->isVector() || (src->getNominalSize() != dst->getNominalSize()))) ||
- (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize()) || (src->getSecondarySize() != dst->getSecondarySize())))))
+ if((src->isVector() && (!dst->isVector() || (src->getNominalSize() != dst->getNominalSize()))) ||
+ (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize()) || (src->getSecondarySize() != dst->getSecondarySize()))))
{
return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");
}
@@ -2303,41 +2497,106 @@
{
Instruction *insert = new Instruction(sw::Shader::OPCODE_INSERT);
- Temporary address(this);
- lvalue(insert->dst, address, dst);
+ lvalue(insert->dst, dst);
insert->src[0].type = insert->dst.type;
insert->src[0].index = insert->dst.index;
insert->src[0].rel = insert->dst.rel;
- argument(insert->src[1], src);
- argument(insert->src[2], binary->getRight());
+ source(insert->src[1], src);
+ source(insert->src[2], binary->getRight());
shader->append(insert);
}
else
{
- for(int offset = 0; offset < dst->totalRegisterCount(); offset++)
+ Instruction *mov1 = new Instruction(sw::Shader::OPCODE_MOV);
+
+ int swizzle = lvalue(mov1->dst, dst);
+
+ source(mov1->src[0], src);
+ mov1->src[0].swizzle = swizzleSwizzle(mov1->src[0].swizzle, swizzle);
+
+ shader->append(mov1);
+
+ for(int offset = 1; offset < dst->totalRegisterCount(); offset++)
{
Instruction *mov = new Instruction(sw::Shader::OPCODE_MOV);
- Temporary address(this);
- int swizzle = lvalue(mov->dst, address, dst);
+ mov->dst = mov1->dst;
mov->dst.index += offset;
+ mov->dst.mask = writeMask(dst, offset);
- if(offset > 0)
- {
- mov->dst.mask = writeMask(dst, offset);
- }
-
- argument(mov->src[0], src, offset);
- mov->src[0].swizzle = swizzleSwizzle(mov->src[0].swizzle, swizzle);
+ source(mov->src[0], src, offset);
shader->append(mov);
}
}
}
- int OutputASM::lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node)
+ void OutputASM::evaluateRvalue(TIntermTyped *node)
+ {
+ TIntermBinary *binary = node->getAsBinaryNode();
+
+ if(binary && binary->getOp() == EOpIndexIndirect && binary->getLeft()->isVector() && node->isScalar())
+ {
+ Instruction *insert = new Instruction(sw::Shader::OPCODE_EXTRACT);
+
+ destination(insert->dst, node);
+
+ Temporary address(this);
+ unsigned char mask;
+ TIntermTyped *root = nullptr;
+ unsigned int offset = 0;
+ int swizzle = lvalue(root, offset, insert->src[0].rel, mask, address, node);
+
+ source(insert->src[0], root, offset);
+ insert->src[0].swizzle = swizzleSwizzle(insert->src[0].swizzle, swizzle);
+
+ source(insert->src[1], binary->getRight());
+
+ shader->append(insert);
+ }
+ else
+ {
+ Instruction *mov1 = new Instruction(sw::Shader::OPCODE_MOV);
+
+ destination(mov1->dst, node, 0);
+
+ Temporary address(this);
+ unsigned char mask;
+ TIntermTyped *root = nullptr;
+ unsigned int offset = 0;
+ int swizzle = lvalue(root, offset, mov1->src[0].rel, mask, address, node);
+
+ source(mov1->src[0], root, offset);
+ mov1->src[0].swizzle = swizzleSwizzle(mov1->src[0].swizzle, swizzle);
+
+ shader->append(mov1);
+
+ for(int i = 1; i < node->totalRegisterCount(); i++)
+ {
+ Instruction *mov = emit(sw::Shader::OPCODE_MOV, node, i, root, offset + i);
+ mov->src[0].rel = mov1->src[0].rel;
+ }
+ }
+ }
+
+ int OutputASM::lvalue(sw::Shader::DestinationParameter &dst, TIntermTyped *node)
+ {
+ Temporary address(this);
+ TIntermTyped *root = nullptr;
+ unsigned int offset = 0;
+ unsigned char mask = 0xF;
+ int swizzle = lvalue(root, offset, dst.rel, mask, address, node);
+
+ dst.type = registerType(root);
+ dst.index = registerIndex(root) + offset;
+ dst.mask = mask;
+
+ return swizzle;
+ }
+
+ int OutputASM::lvalue(TIntermTyped *&root, unsigned int &offset, sw::Shader::Relative &rel, unsigned char &mask, Temporary &address, TIntermTyped *node)
{
TIntermTyped *result = node;
TIntermBinary *binary = node->getAsBinaryNode();
@@ -2348,7 +2607,7 @@
TIntermTyped *left = binary->getLeft();
TIntermTyped *right = binary->getRight();
- int leftSwizzle = lvalue(dst, address, left); // Resolve the l-value of the left side
+ int leftSwizzle = lvalue(root, offset, rel, mask, address, left); // Resolve the l-value of the left side
switch(binary->getOp())
{
@@ -2358,22 +2617,22 @@
if(left->isRegister())
{
- int leftMask = dst.mask;
+ int leftMask = mask;
- dst.mask = 1;
- while((leftMask & dst.mask) == 0)
+ mask = 1;
+ while((leftMask & mask) == 0)
{
- dst.mask = dst.mask << 1;
+ mask = mask << 1;
}
int element = swizzleElement(leftSwizzle, rightIndex);
- dst.mask = 1 << element;
+ mask = 1 << element;
return element;
}
else if(left->isArray() || left->isMatrix())
{
- dst.index += rightIndex * result->totalRegisterCount();
+ offset += rightIndex * result->totalRegisterCount();
return 0xE4;
}
else UNREACHABLE(0);
@@ -2381,6 +2640,8 @@
break;
case EOpIndexIndirect:
{
+ right->traverse(this);
+
if(left->isRegister())
{
// Requires INSERT instruction (handled by calling function)
@@ -2389,42 +2650,42 @@
{
int scale = result->totalRegisterCount();
- if(dst.rel.type == sw::Shader::PARAMETER_VOID) // Use the index register as the relative address directly
+ if(rel.type == sw::Shader::PARAMETER_VOID) // Use the index register as the relative address directly
{
if(left->totalRegisterCount() > 1)
{
sw::Shader::SourceParameter relativeRegister;
- argument(relativeRegister, right);
+ source(relativeRegister, right);
- dst.rel.index = relativeRegister.index;
- dst.rel.type = relativeRegister.type;
- dst.rel.scale = scale;
- dst.rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
+ rel.index = relativeRegister.index;
+ rel.type = relativeRegister.type;
+ rel.scale = scale;
+ rel.deterministic = !(vertexShader && left->getQualifier() == EvqUniform);
}
}
- else if(dst.rel.index != registerIndex(&address)) // Move the previous index register to the address register
+ else if(rel.index != registerIndex(&address)) // Move the previous index register to the address register
{
if(scale == 1)
{
- Constant oldScale((int)dst.rel.scale);
+ Constant oldScale((int)rel.scale);
Instruction *mad = emit(sw::Shader::OPCODE_IMAD, &address, &address, &oldScale, right);
- mad->src[0].index = dst.rel.index;
- mad->src[0].type = dst.rel.type;
+ mad->src[0].index = rel.index;
+ mad->src[0].type = rel.type;
}
else
{
- Constant oldScale((int)dst.rel.scale);
+ Constant oldScale((int)rel.scale);
Instruction *mul = emit(sw::Shader::OPCODE_IMUL, &address, &address, &oldScale);
- mul->src[0].index = dst.rel.index;
- mul->src[0].type = dst.rel.type;
+ mul->src[0].index = rel.index;
+ mul->src[0].type = rel.type;
Constant newScale(scale);
emit(sw::Shader::OPCODE_IMAD, &address, right, &newScale, &address);
}
- dst.rel.type = sw::Shader::PARAMETER_TEMP;
- dst.rel.index = registerIndex(&address);
- dst.rel.scale = 1;
+ rel.type = sw::Shader::PARAMETER_TEMP;
+ rel.index = registerIndex(&address);
+ rel.scale = 1;
}
else // Just add the new index to the address register
{
@@ -2456,9 +2717,8 @@
fieldOffset += fields[i]->type()->totalRegisterCount();
}
- dst.type = registerType(left);
- dst.index += fieldOffset;
- dst.mask = writeMask(result);
+ offset += fieldOffset;
+ mask = writeMask(result);
return 0xE4;
}
@@ -2467,7 +2727,7 @@
{
ASSERT(left->isRegister());
- int leftMask = dst.mask;
+ int leftMask = mask;
int swizzle = 0;
int rightMask = 0;
@@ -2483,7 +2743,7 @@
swizzle = swizzle | swizzleElement(leftSwizzle, i) << (element * 2);
}
- dst.mask = leftMask & rightMask;
+ mask = leftMask & rightMask;
return swizzle;
}
@@ -2495,9 +2755,20 @@
}
else if(symbol)
{
- dst.type = registerType(symbol);
- dst.index = registerIndex(symbol);
- dst.mask = writeMask(symbol);
+ root = symbol;
+ offset = 0;
+ mask = writeMask(symbol);
+
+ return 0xE4;
+ }
+ else
+ {
+ node->traverse(this);
+
+ root = node;
+ offset = 0;
+ mask = writeMask(node);
+
return 0xE4;
}
@@ -2512,10 +2783,10 @@
}
const TQualifier qualifier = operand->getQualifier();
- if((EvqFragColor == qualifier) || (EvqFragData == qualifier))
+ if((qualifier == EvqFragColor) || (qualifier == EvqFragData))
{
- if(((EvqFragData == qualifier) && (EvqFragColor == outputQualifier)) ||
- ((EvqFragColor == qualifier) && (EvqFragData == outputQualifier)))
+ if(((qualifier == EvqFragData) && (outputQualifier == EvqFragColor)) ||
+ ((qualifier == EvqFragColor) && (outputQualifier == EvqFragData)))
{
mContext.error(operand->getLine(), "static assignment to both gl_FragData and gl_FragColor", "");
}
@@ -2524,7 +2795,15 @@
if(qualifier == EvqConstExpr && (!operand->getAsConstantUnion() || !operand->getAsConstantUnion()->getUnionArrayPointer()))
{
- return sw::Shader::PARAMETER_TEMP;
+ // Constant arrays are in the constant register file.
+ if(operand->isArray() && operand->getArraySize() > 1)
+ {
+ return sw::Shader::PARAMETER_CONST;
+ }
+ else
+ {
+ return sw::Shader::PARAMETER_TEMP;
+ }
}
switch(qualifier)
@@ -2755,6 +3034,28 @@
return allocate(temporaries, temporary);
}
+ void OutputASM::setPixelShaderInputs(const TType& type, int var, bool flat)
+ {
+ if(type.isStruct())
+ {
+ const TFieldList &fields = type.getStruct()->fields();
+ int fieldVar = var;
+ for(const auto &field : fields)
+ {
+ const TType& fieldType = *(field->type());
+ setPixelShaderInputs(fieldType, fieldVar, flat);
+ fieldVar += fieldType.totalRegisterCount();
+ }
+ }
+ else
+ {
+ for(int i = 0; i < type.totalRegisterCount(); i++)
+ {
+ pixelShader->setInput(var + i, type.registerSize(), sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat));
+ }
+ }
+ }
+
int OutputASM::varyingRegister(TIntermTyped *varying)
{
int var = lookup(varyings, varying);
@@ -2762,7 +3063,6 @@
if(var == -1)
{
var = allocate(varyings, varying);
- int componentCount = varying->registerSize();
int registerCount = varying->totalRegisterCount();
if(pixelShader)
@@ -2776,16 +3076,11 @@
if(varying->getQualifier() == EvqPointCoord)
{
ASSERT(varying->isRegister());
- pixelShader->setInput(var, componentCount, sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var));
+ pixelShader->setInput(var, varying->registerSize(), sw::Shader::Semantic(sw::Shader::USAGE_TEXCOORD, var));
}
else
{
- for(int i = 0; i < varying->totalRegisterCount(); i++)
- {
- bool flat = hasFlatQualifier(varying);
-
- pixelShader->setInput(var + i, componentCount, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, var + i, flat));
- }
+ setPixelShaderInputs(varying->getType(), var, hasFlatQualifier(varying));
}
}
else if(vertexShader)
@@ -2823,26 +3118,105 @@
{
if(varying->getQualifier() != EvqPointCoord) // gl_PointCoord does not need linking
{
- const TType &type = varying->getType();
- const char *name = varying->getAsSymbolNode()->getSymbol().c_str();
- VaryingList &activeVaryings = shaderObject->varyings;
+ TIntermSymbol *symbol = varying->getAsSymbolNode();
+ declareVarying(varying->getType(), symbol->getSymbol(), reg);
+ }
+ }
+ void OutputASM::declareVarying(const TType &type, const TString &varyingName, int registerIndex)
+ {
+ const char *name = varyingName.c_str();
+ VaryingList &activeVaryings = shaderObject->varyings;
+
+ TStructure* structure = type.getStruct();
+ if(structure)
+ {
+ int fieldRegisterIndex = registerIndex;
+
+ const TFieldList &fields = type.getStruct()->fields();
+ for(const auto &field : fields)
+ {
+ const TType& fieldType = *(field->type());
+ declareVarying(fieldType, varyingName + "." + field->name(), fieldRegisterIndex);
+ if(fieldRegisterIndex >= 0)
+ {
+ fieldRegisterIndex += fieldType.totalRegisterCount();
+ }
+ }
+ }
+ else
+ {
// Check if this varying has been declared before without having a register assigned
for(VaryingList::iterator v = activeVaryings.begin(); v != activeVaryings.end(); v++)
{
if(v->name == name)
{
- if(reg >= 0)
+ if(registerIndex >= 0)
{
- ASSERT(v->reg < 0 || v->reg == reg);
- v->reg = reg;
+ ASSERT(v->registerIndex < 0 || v->registerIndex == registerIndex);
+ v->registerIndex = registerIndex;
}
return;
}
}
- activeVaryings.push_back(glsl::Varying(glVariableType(type), name, varying->getArraySize(), reg, 0));
+ activeVaryings.push_back(glsl::Varying(type, name, registerIndex, 0));
+ }
+ }
+
+ void OutputASM::declareFragmentOutput(TIntermTyped *fragmentOutput)
+ {
+ int requestedLocation = fragmentOutput->getType().getLayoutQualifier().location;
+ int registerCount = fragmentOutput->totalRegisterCount();
+ if(requestedLocation < 0)
+ {
+ ASSERT(requestedLocation == -1); // All other negative values would have been prevented in TParseContext::parseLayoutQualifier
+ return; // No requested location
+ }
+ else if((requestedLocation + registerCount) > sw::RENDERTARGETS)
+ {
+ mContext.error(fragmentOutput->getLine(), "Fragment output location larger or equal to MAX_DRAW_BUFFERS", "fragment shader");
+ }
+ else
+ {
+ int currentIndex = lookup(fragmentOutputs, fragmentOutput);
+ if(requestedLocation != currentIndex)
+ {
+ if(currentIndex != -1)
+ {
+ mContext.error(fragmentOutput->getLine(), "Multiple locations for fragment output", "fragment shader");
+ }
+ else
+ {
+ if(fragmentOutputs.size() <= (size_t)requestedLocation)
+ {
+ while(fragmentOutputs.size() < (size_t)requestedLocation)
+ {
+ fragmentOutputs.push_back(nullptr);
+ }
+ for(int i = 0; i < registerCount; i++)
+ {
+ fragmentOutputs.push_back(fragmentOutput);
+ }
+ }
+ else
+ {
+ for(int i = 0; i < registerCount; i++)
+ {
+ if(!fragmentOutputs[requestedLocation + i])
+ {
+ fragmentOutputs[requestedLocation + i] = fragmentOutput;
+ }
+ else
+ {
+ mContext.error(fragmentOutput->getLine(), "Fragment output location aliasing", "fragment shader");
+ return;
+ }
+ }
+ }
+ }
+ }
}
}
@@ -2872,7 +3246,7 @@
int blockMemberIndex = blockMemberLookup(type, name, index);
if(blockMemberIndex == -1)
{
- declareUniform(type, name, index);
+ declareUniform(type, name, index, false);
}
else
{
@@ -2973,7 +3347,7 @@
{
case EOpIndexDirect:
ASSERT(left->isArray());
- offset = index * leftType.elementRegisterCount();
+ offset = index * leftType.samplerRegisterCount();
break;
case EOpIndexDirectStruct:
ASSERT(leftType.isStruct());
@@ -2982,7 +3356,7 @@
for(int i = 0; i < index; i++)
{
- offset += fields[i]->type()->totalRegisterCount();
+ offset += fields[i]->type()->totalSamplerRegisterCount();
}
}
break;
@@ -3017,12 +3391,12 @@
if(index == -1)
{
- index = allocate(samplers, sampler);
+ index = allocate(samplers, sampler, true);
if(sampler->getQualifier() == EvqUniform)
{
const char *name = sampler->getSymbol().c_str();
- declareUniform(type, name, index);
+ declareUniform(type, name, index, true);
}
}
@@ -3108,13 +3482,13 @@
return -1;
}
- int OutputASM::allocate(VariableArray &list, TIntermTyped *variable)
+ int OutputASM::allocate(VariableArray &list, TIntermTyped *variable, bool samplersOnly)
{
int index = lookup(list, variable);
if(index == -1)
{
- unsigned int registerCount = variable->blockRegisterCount();
+ unsigned int registerCount = variable->blockRegisterCount(samplersOnly);
for(unsigned int i = 0; i < list.size(); i++)
{
@@ -3202,7 +3576,7 @@
return -1;
}
- void OutputASM::declareUniform(const TType &type, const TString &name, int registerIndex, int blockId, BlockLayoutEncoder* encoder)
+ void OutputASM::declareUniform(const TType &type, const TString &name, int registerIndex, bool samplersOnly, int blockId, BlockLayoutEncoder* encoder)
{
const TStructure *structure = type.getStruct();
const TInterfaceBlock *block = (type.isInterfaceBlock() || (blockId == -1)) ? type.getInterfaceBlock() : nullptr;
@@ -3213,19 +3587,22 @@
const BlockMemberInfo blockInfo = encoder ? encoder->encodeType(type) : BlockMemberInfo::getDefaultBlockInfo();
if(blockId >= 0)
{
- blockDefinitions[blockId][registerIndex] = TypedMemberInfo(blockInfo, type);
+ blockDefinitions[blockId].insert(BlockDefinitionIndexMap::value_type(registerIndex, TypedMemberInfo(blockInfo, type)));
shaderObject->activeUniformBlocks[blockId].fields.push_back(activeUniforms.size());
}
int fieldRegisterIndex = encoder ? shaderObject->activeUniformBlocks[blockId].registerIndex + BlockLayoutEncoder::getBlockRegister(blockInfo) : registerIndex;
- activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(),
- fieldRegisterIndex, blockId, blockInfo));
- if(IsSampler(type.getBasicType()))
+ bool isSampler = IsSampler(type.getBasicType());
+ if(isSampler && samplersOnly)
{
for(int i = 0; i < type.totalRegisterCount(); i++)
{
shader->declareSampler(fieldRegisterIndex + i);
}
}
+ if(isSampler == samplersOnly)
+ {
+ activeUniforms.push_back(Uniform(type, name.c_str(), fieldRegisterIndex, blockId, blockInfo));
+ }
}
else if(block)
{
@@ -3241,12 +3618,12 @@
block->blockStorage(), isRowMajor, registerIndex, blockId));
blockDefinitions.push_back(BlockDefinitionIndexMap());
- Std140BlockEncoder currentBlockEncoder(isRowMajor);
+ Std140BlockEncoder currentBlockEncoder;
currentBlockEncoder.enterAggregateType();
- for(size_t i = 0; i < fields.size(); i++)
+ for(const auto &field : fields)
{
- const TType &fieldType = *(fields[i]->type());
- const TString &fieldName = fields[i]->name();
+ const TType &fieldType = *(field->type());
+ const TString &fieldName = field->name();
if(isUniformBlockMember && (fieldName == name))
{
registerIndex = fieldRegisterIndex;
@@ -3254,7 +3631,7 @@
const TString uniformName = block->hasInstanceName() ? blockName + "." + fieldName : fieldName;
- declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, ¤tBlockEncoder);
+ declareUniform(fieldType, uniformName, fieldRegisterIndex, samplersOnly, blockId, ¤tBlockEncoder);
fieldRegisterIndex += fieldType.totalRegisterCount();
}
currentBlockEncoder.exitAggregateType();
@@ -3262,6 +3639,9 @@
}
else
{
+ // Store struct for program link time validation
+ shaderObject->activeUniformStructs.push_back(Uniform(type, name.c_str(), registerIndex, -1, BlockMemberInfo::getDefaultBlockInfo()));
+
int fieldRegisterIndex = registerIndex;
const TFieldList& fields = structure->fields();
@@ -3273,14 +3653,14 @@
{
encoder->enterAggregateType();
}
- for(size_t j = 0; j < fields.size(); j++)
+ for(const auto &field : fields)
{
- const TType &fieldType = *(fields[j]->type());
- const TString &fieldName = fields[j]->name();
+ const TType &fieldType = *(field->type());
+ const TString &fieldName = field->name();
const TString uniformName = name + "[" + str(i) + "]." + fieldName;
- declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder);
- fieldRegisterIndex += fieldType.totalRegisterCount();
+ declareUniform(fieldType, uniformName, fieldRegisterIndex, samplersOnly, blockId, encoder);
+ fieldRegisterIndex += samplersOnly ? fieldType.totalSamplerRegisterCount() : fieldType.totalRegisterCount();
}
if(encoder)
{
@@ -3294,14 +3674,14 @@
{
encoder->enterAggregateType();
}
- for(size_t i = 0; i < fields.size(); i++)
+ for(const auto &field : fields)
{
- const TType &fieldType = *(fields[i]->type());
- const TString &fieldName = fields[i]->name();
+ const TType &fieldType = *(field->type());
+ const TString &fieldName = field->name();
const TString uniformName = name + "." + fieldName;
- declareUniform(fieldType, uniformName, fieldRegisterIndex, blockId, encoder);
- fieldRegisterIndex += fieldType.totalRegisterCount();
+ declareUniform(fieldType, uniformName, fieldRegisterIndex, samplersOnly, blockId, encoder);
+ fieldRegisterIndex += samplersOnly ? fieldType.totalSamplerRegisterCount() : fieldType.totalRegisterCount();
}
if(encoder)
{
@@ -3311,180 +3691,6 @@
}
}
- GLenum OutputASM::glVariableType(const TType &type)
- {
- switch(type.getBasicType())
- {
- case EbtFloat:
- if(type.isScalar())
- {
- return GL_FLOAT;
- }
- else if(type.isVector())
- {
- switch(type.getNominalSize())
- {
- case 2: return GL_FLOAT_VEC2;
- case 3: return GL_FLOAT_VEC3;
- case 4: return GL_FLOAT_VEC4;
- default: UNREACHABLE(type.getNominalSize());
- }
- }
- else if(type.isMatrix())
- {
- switch(type.getNominalSize())
- {
- case 2:
- switch(type.getSecondarySize())
- {
- case 2: return GL_FLOAT_MAT2;
- case 3: return GL_FLOAT_MAT2x3;
- case 4: return GL_FLOAT_MAT2x4;
- default: UNREACHABLE(type.getSecondarySize());
- }
- case 3:
- switch(type.getSecondarySize())
- {
- case 2: return GL_FLOAT_MAT3x2;
- case 3: return GL_FLOAT_MAT3;
- case 4: return GL_FLOAT_MAT3x4;
- default: UNREACHABLE(type.getSecondarySize());
- }
- case 4:
- switch(type.getSecondarySize())
- {
- case 2: return GL_FLOAT_MAT4x2;
- case 3: return GL_FLOAT_MAT4x3;
- case 4: return GL_FLOAT_MAT4;
- default: UNREACHABLE(type.getSecondarySize());
- }
- default: UNREACHABLE(type.getNominalSize());
- }
- }
- else UNREACHABLE(0);
- break;
- case EbtInt:
- if(type.isScalar())
- {
- return GL_INT;
- }
- else if(type.isVector())
- {
- switch(type.getNominalSize())
- {
- case 2: return GL_INT_VEC2;
- case 3: return GL_INT_VEC3;
- case 4: return GL_INT_VEC4;
- default: UNREACHABLE(type.getNominalSize());
- }
- }
- else UNREACHABLE(0);
- break;
- case EbtUInt:
- if(type.isScalar())
- {
- return GL_UNSIGNED_INT;
- }
- else if(type.isVector())
- {
- switch(type.getNominalSize())
- {
- case 2: return GL_UNSIGNED_INT_VEC2;
- case 3: return GL_UNSIGNED_INT_VEC3;
- case 4: return GL_UNSIGNED_INT_VEC4;
- default: UNREACHABLE(type.getNominalSize());
- }
- }
- else UNREACHABLE(0);
- break;
- case EbtBool:
- if(type.isScalar())
- {
- return GL_BOOL;
- }
- else if(type.isVector())
- {
- switch(type.getNominalSize())
- {
- case 2: return GL_BOOL_VEC2;
- case 3: return GL_BOOL_VEC3;
- case 4: return GL_BOOL_VEC4;
- default: UNREACHABLE(type.getNominalSize());
- }
- }
- else UNREACHABLE(0);
- break;
- case EbtSampler2D:
- return GL_SAMPLER_2D;
- case EbtISampler2D:
- return GL_INT_SAMPLER_2D;
- case EbtUSampler2D:
- return GL_UNSIGNED_INT_SAMPLER_2D;
- case EbtSamplerCube:
- return GL_SAMPLER_CUBE;
- case EbtISamplerCube:
- return GL_INT_SAMPLER_CUBE;
- case EbtUSamplerCube:
- return GL_UNSIGNED_INT_SAMPLER_CUBE;
- case EbtSamplerExternalOES:
- return GL_SAMPLER_EXTERNAL_OES;
- case EbtSampler3D:
- return GL_SAMPLER_3D_OES;
- case EbtISampler3D:
- return GL_INT_SAMPLER_3D;
- case EbtUSampler3D:
- return GL_UNSIGNED_INT_SAMPLER_3D;
- case EbtSampler2DArray:
- return GL_SAMPLER_2D_ARRAY;
- case EbtISampler2DArray:
- return GL_INT_SAMPLER_2D_ARRAY;
- case EbtUSampler2DArray:
- return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
- case EbtSampler2DShadow:
- return GL_SAMPLER_2D_SHADOW;
- case EbtSamplerCubeShadow:
- return GL_SAMPLER_CUBE_SHADOW;
- case EbtSampler2DArrayShadow:
- return GL_SAMPLER_2D_ARRAY_SHADOW;
- default:
- UNREACHABLE(type.getBasicType());
- break;
- }
-
- return GL_NONE;
- }
-
- GLenum OutputASM::glVariablePrecision(const TType &type)
- {
- if(type.getBasicType() == EbtFloat)
- {
- switch(type.getPrecision())
- {
- case EbpHigh: return GL_HIGH_FLOAT;
- case EbpMedium: return GL_MEDIUM_FLOAT;
- case EbpLow: return GL_LOW_FLOAT;
- case EbpUndefined:
- // Should be defined as the default precision by the parser
- default: UNREACHABLE(type.getPrecision());
- }
- }
- else if(type.getBasicType() == EbtInt)
- {
- switch(type.getPrecision())
- {
- case EbpHigh: return GL_HIGH_INT;
- case EbpMedium: return GL_MEDIUM_INT;
- case EbpLow: return GL_LOW_INT;
- case EbpUndefined:
- // Should be defined as the default precision by the parser
- default: UNREACHABLE(type.getPrecision());
- }
- }
-
- // Other types (boolean, sampler) don't have a precision
- return GL_NONE;
- }
-
int OutputASM::dim(TIntermNode *v)
{
TIntermTyped *vector = v->getAsTyped();
diff --git a/src/OpenGL/compiler/OutputASM.h b/src/OpenGL/compiler/OutputASM.h
index 34f154a..3391035 100644
--- a/src/OpenGL/compiler/OutputASM.h
+++ b/src/OpenGL/compiler/OutputASM.h
@@ -55,9 +55,9 @@
bool isRowMajorMatrix;
};
- struct Uniform
+ struct ShaderVariable
{
- Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo);
+ ShaderVariable(const TType& type, const std::string& name, int registerIndex);
GLenum type;
GLenum precision;
@@ -66,6 +66,13 @@
int registerIndex;
+ std::vector<ShaderVariable> fields;
+ };
+
+ struct Uniform : public ShaderVariable
+ {
+ Uniform(const TType& type, const std::string &name, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo);
+
int blockId;
BlockMemberInfo blockInfo;
};
@@ -92,7 +99,7 @@
class BlockLayoutEncoder
{
public:
- BlockLayoutEncoder(bool rowMajor);
+ BlockLayoutEncoder();
virtual ~BlockLayoutEncoder() {}
BlockMemberInfo encodeType(const TType &type);
@@ -110,7 +117,6 @@
protected:
size_t mCurrentOffset;
- bool isRowMajor;
void nextRegister();
@@ -123,7 +129,7 @@
class Std140BlockEncoder : public BlockLayoutEncoder
{
public:
- Std140BlockEncoder(bool rowMajor);
+ Std140BlockEncoder();
void enterAggregateType() override;
void exitAggregateType() override;
@@ -150,10 +156,10 @@
typedef std::vector<Attribute> ActiveAttributes;
- struct Varying
+ struct Varying : public ShaderVariable
{
- Varying(GLenum type, const std::string &name, int arraySize, int reg = -1, int col = -1)
- : type(type), name(name), arraySize(arraySize), reg(reg), col(col)
+ Varying(const TType& type, const std::string &name, int reg = -1, int col = -1)
+ : ShaderVariable(type, name, reg), qualifier(type.getQualifier()), column(col)
{
}
@@ -167,12 +173,8 @@
return arraySize > 0 ? arraySize : 1;
}
- GLenum type;
- std::string name;
- int arraySize;
-
- int reg; // First varying register, assigned during link
- int col; // First register element, assigned during link
+ TQualifier qualifier;
+ int column; // First register element, assigned during link
};
typedef std::list<Varying> VaryingList;
@@ -185,12 +187,15 @@
virtual sw::Shader *getShader() const = 0;
virtual sw::PixelShader *getPixelShader() const;
virtual sw::VertexShader *getVertexShader() const;
+ int getShaderVersion() const { return shaderVersion; }
protected:
VaryingList varyings;
ActiveUniforms activeUniforms;
+ ActiveUniforms activeUniformStructs;
ActiveAttributes activeAttributes;
ActiveUniformBlocks activeUniformBlocks;
+ int shaderVersion;
};
struct Function
@@ -240,7 +245,7 @@
LOD,
SIZE, // textureSize()
FETCH,
- GRAD
+ GRAD,
};
Method method;
@@ -251,14 +256,14 @@
void emitShader(Scope scope);
// Visit AST nodes and output their code to the body stream
- virtual void visitSymbol(TIntermSymbol*);
- virtual bool visitBinary(Visit visit, TIntermBinary*);
- virtual bool visitUnary(Visit visit, TIntermUnary*);
- virtual bool visitSelection(Visit visit, TIntermSelection*);
- virtual bool visitAggregate(Visit visit, TIntermAggregate*);
- virtual bool visitLoop(Visit visit, TIntermLoop*);
- virtual bool visitBranch(Visit visit, TIntermBranch*);
- virtual bool visitSwitch(Visit, TIntermSwitch*);
+ void visitSymbol(TIntermSymbol*) override;
+ bool visitBinary(Visit visit, TIntermBinary*) override;
+ bool visitUnary(Visit visit, TIntermUnary*) override;
+ bool visitSelection(Visit visit, TIntermSelection*) override;
+ bool visitAggregate(Visit visit, TIntermAggregate*) override;
+ bool visitLoop(Visit visit, TIntermLoop*) override;
+ bool visitBranch(Visit visit, TIntermBranch*) override;
+ bool visitSwitch(Visit, TIntermSwitch*) override;
sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;
Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, TIntermNode *src4 = 0);
@@ -270,10 +275,13 @@
void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);
void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);
void emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0);
- void argument(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index = 0);
+ void source(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index = 0);
+ void destination(sw::Shader::DestinationParameter ¶meter, TIntermTyped *argument, int index = 0);
void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
- int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
+ void evaluateRvalue(TIntermTyped *node);
+ int lvalue(sw::Shader::DestinationParameter &dst, TIntermTyped *node);
+ int lvalue(TIntermTyped *&root, unsigned int &offset, sw::Shader::Relative &rel, unsigned char &mask, Temporary &address, TIntermTyped *node);
sw::Shader::ParameterType registerType(TIntermTyped *operand);
bool hasFlatQualifier(TIntermTyped *operand);
unsigned int registerIndex(TIntermTyped *operand);
@@ -285,7 +293,10 @@
int temporaryRegister(TIntermTyped *temporary);
int varyingRegister(TIntermTyped *varying);
+ void setPixelShaderInputs(const TType& type, int var, bool flat);
void declareVarying(TIntermTyped *varying, int reg);
+ void declareVarying(const TType &type, const TString &name, int registerIndex);
+ void declareFragmentOutput(TIntermTyped *fragmentOutput);
int uniformRegister(TIntermTyped *uniform);
int attributeRegister(TIntermTyped *attribute);
int fragmentOutputRegister(TIntermTyped *fragmentOutput);
@@ -298,12 +309,10 @@
int lookup(VariableArray &list, TIntermTyped *variable);
int lookup(VariableArray &list, TInterfaceBlock *block);
int blockMemberLookup(const TType &type, const TString &name, int registerIndex);
- int allocate(VariableArray &list, TIntermTyped *variable);
+ int allocate(VariableArray &list, TIntermTyped *variable, bool samplersOnly = false);
void free(VariableArray &list, TIntermTyped *variable);
- void declareUniform(const TType &type, const TString &name, int registerIndex, int blockId = -1, BlockLayoutEncoder* encoder = nullptr);
- GLenum glVariableType(const TType &type);
- GLenum glVariablePrecision(const TType &type);
+ void declareUniform(const TType &type, const TString &name, int registerIndex, bool samplersOnly, int blockId = -1, BlockLayoutEncoder* encoder = nullptr);
static int dim(TIntermNode *v);
static int dim2(TIntermNode *m);
@@ -323,7 +332,6 @@
struct TypedMemberInfo : public BlockMemberInfo
{
- TypedMemberInfo() {}
TypedMemberInfo(const BlockMemberInfo& b, const TType& t) : BlockMemberInfo(b), type(t) {}
TType type;
};
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp
index 3fea084..c7100ba 100644
--- a/src/OpenGL/compiler/ParseHelper.cpp
+++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -14,6 +14,7 @@
#include "ParseHelper.h"
+#include <limits>
#include <stdarg.h>
#include <stdio.h>
@@ -189,55 +190,6 @@
return true;
}
-
-//
-// Look at a '.' field selector string and change it into offsets
-// for a matrix.
-//
-bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc &line)
-{
- fields.wholeRow = false;
- fields.wholeCol = false;
- fields.row = -1;
- fields.col = -1;
-
- if (compString.size() != 2) {
- error(line, "illegal length of matrix field selection", compString.c_str());
- return false;
- }
-
- if (compString[0] == '_') {
- if (compString[1] < '0' || compString[1] > '3') {
- error(line, "illegal matrix field selection", compString.c_str());
- return false;
- }
- fields.wholeCol = true;
- fields.col = compString[1] - '0';
- } else if (compString[1] == '_') {
- if (compString[0] < '0' || compString[0] > '3') {
- error(line, "illegal matrix field selection", compString.c_str());
- return false;
- }
- fields.wholeRow = true;
- fields.row = compString[0] - '0';
- } else {
- if (compString[0] < '0' || compString[0] > '3' ||
- compString[1] < '0' || compString[1] > '3') {
- error(line, "illegal matrix field selection", compString.c_str());
- return false;
- }
- fields.row = compString[0] - '0';
- fields.col = compString[1] - '0';
- }
-
- if (fields.row >= matRows || fields.col >= matCols) {
- error(line, "matrix field selection out of range", compString.c_str());
- return false;
- }
-
- return true;
-}
-
///////////////////////////////////////////////////////////////////////
//
// Errors
@@ -352,7 +304,6 @@
case EOpIndexDirect:
case EOpIndexIndirect:
case EOpIndexDirectStruct:
- case EOpIndexDirectInterfaceBlock:
return lValueErrorCheck(line, op, binaryNode->getLeft());
case EOpVectorSwizzle:
errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
@@ -375,6 +326,7 @@
}
return errorReturn;
+ case EOpIndexDirectInterfaceBlock:
default:
break;
}
@@ -829,9 +781,8 @@
return true;
if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
- const TFieldList& fields = type.getStruct()->fields();
- for(unsigned int i = 0; i < fields.size(); ++i) {
- if (containsSampler(*fields[i]->type()))
+ for(const auto &field : type.getStruct()->fields()) {
+ if (containsSampler(*(field->type())))
return true;
}
}
@@ -1066,7 +1017,7 @@
return false;
(*variable) = new TVariable(&identifier, type);
- if(!symbolTable.declare(**variable))
+ if(!symbolTable.declare(*variable))
{
error(line, "redefinition", identifier.c_str());
delete (*variable);
@@ -1171,10 +1122,10 @@
mDirectiveHandler.handleExtension(loc, extName, behavior);
}
-void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value)
+void TParseContext::handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value, bool stdgl)
{
pp::SourceLocation loc(line.first_file, line.first_line);
- mDirectiveHandler.handlePragma(loc, name, value);
+ mDirectiveHandler.handlePragma(loc, name, value, stdgl);
}
/////////////////////////////////////////////////////////////////////////////////
@@ -1234,7 +1185,7 @@
{
TType type(EbtFloat, EbpUndefined);
TVariable *fakeVariable = new TVariable(name, type);
- symbolTable.declare(*fakeVariable);
+ symbolTable.declare(fakeVariable);
variable = fakeVariable;
}
@@ -1251,11 +1202,11 @@
// First find by unmangled name to check whether the function name has been
// hidden by a variable name or struct typename.
const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn);
- if (symbol == 0) {
+ if (!symbol || symbol->isFunction()) {
symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn);
}
- if (symbol == 0) {
+ if (!symbol) {
error(line, "no matching overloaded function found", call->getName().c_str());
return nullptr;
}
@@ -1345,15 +1296,21 @@
}
}
- if (!variable->isConstant()) {
+ // Constants which aren't indexable arrays get propagated by value
+ // and thus don't need to initialize the symbol.
+ if (variable->isConstant() && !(type.isArray() && type.getArraySize() > 1))
+ {
+ *intermNode = nullptr;
+ }
+ else
+ {
TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
*intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
if(*intermNode == nullptr) {
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return true;
}
- } else
- *intermNode = nullptr;
+ }
return false;
}
@@ -1365,13 +1322,6 @@
returnType.invariant = invariant;
returnType.layoutQualifier = layoutQualifier;
- if(typeSpecifier.array)
- {
- error(typeSpecifier.line, "not supported", "first-class array");
- recover();
- returnType.clearArrayness();
- }
-
if(mShaderVersion < 300)
{
if(typeSpecifier.array)
@@ -2014,7 +1964,7 @@
//
// Insert the parameters with name in the symbol table.
//
- if(!symbolTable.declare(*variable))
+ if(!symbolTable.declare(variable))
{
error(location, "redefinition", variable->getName().c_str());
recover();
@@ -2090,10 +2040,16 @@
recover();
}
}
+ else
+ {
+ // Insert the unmangled name to detect potential future redefinition as a variable.
+ TFunction *unmangledFunction = new TFunction(NewPoolTString(function->getName().c_str()), function->getReturnType());
+ symbolTable.getOuterLevel()->insertUnmangled(unmangledFunction);
+ }
// We're at the inner scope level of the function's arguments and body statement.
// Add the function prototype to the surrounding scope instead.
- symbolTable.getOuterLevel()->insert(*function);
+ symbolTable.getOuterLevel()->insert(function);
//
// If this is a redeclaration, it could also be a definition, in which case, we want to use the
@@ -2250,7 +2206,9 @@
constArray[i] = unionArray[fields.offsets[i]];
}
- typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
+
+ TType type(node->getType().getBasicType(), node->getType().getPrecision(), EvqConstExpr, fields.num);
+ typedNode = intermediate.addConstantUnion(constArray, type, line);
return typedNode;
}
@@ -2339,11 +2297,11 @@
size_t instanceSize = 0;
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
- for(size_t index = 0; index < fields.size(); ++index) {
- if (fields[index]->name() == identifier) {
+ for(const auto &field : fields) {
+ if (field->name() == identifier) {
break;
} else {
- instanceSize += fields[index]->type()->getObjectSize();
+ instanceSize += field->type()->getObjectSize();
}
}
@@ -2393,14 +2351,13 @@
}
TSymbol* blockNameSymbol = new TSymbol(&blockName);
- if(!symbolTable.declare(*blockNameSymbol)) {
+ if(!symbolTable.declare(blockNameSymbol)) {
error(nameLine, "redefinition", blockName.c_str(), "interface block name");
recover();
}
// check for sampler types and apply layout qualifiers
- for(size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) {
- TField* field = (*fieldList)[memberIndex];
+ for(const auto &field : *fieldList) {
TType* fieldType = field->type();
if(IsSampler(fieldType->getBasicType())) {
error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks");
@@ -2436,13 +2393,15 @@
{
fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
}
- else if(!fieldType->isMatrix())
+ else if(!fieldType->isMatrix() && (fieldType->getBasicType() != EbtStruct))
{
- error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types");
- recover();
+ warning(field->line(), "extraneous layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "only has an effect on matrix types");
}
fieldType->setLayoutQualifier(fieldLayoutQualifier);
+
+ // Recursively propagate the matrix packing setting down to all block/structure members
+ fieldType->setMatrixPackingIfUnspecified(fieldLayoutQualifier.matrixPacking);
}
// add array index
@@ -2462,9 +2421,8 @@
if(!instanceName)
{
// define symbols for the members of the interface block
- for(size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
+ for(const auto &field : *fieldList)
{
- TField* field = (*fieldList)[memberIndex];
TType* fieldType = field->type();
// set parent pointer of the field variable
@@ -2473,7 +2431,7 @@
TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
fieldVariable->setQualifier(typeQualifier.qualifier);
- if(!symbolTable.declare(*fieldVariable)) {
+ if(!symbolTable.declare(fieldVariable)) {
error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
recover();
}
@@ -2481,11 +2439,14 @@
}
else
{
+ if(reservedErrorCheck(nameLine, *instanceName))
+ recover();
+
// add a symbol for this interface block
TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
instanceTypeDef->setQualifier(typeQualifier.qualifier);
- if(!symbolTable.declare(*instanceTypeDef)) {
+ if(!symbolTable.declare(instanceTypeDef)) {
error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
recover();
}
@@ -2524,7 +2485,7 @@
TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
- if(indexExpression->getQualifier() == EvqConstExpr && indexConstantUnion)
+ if(indexExpression->getQualifier() == EvqConstExpr && indexConstantUnion) // TODO: Qualifier check redundant?
{
int index = indexConstantUnion->getIConst(0);
if(index < 0)
@@ -2536,7 +2497,7 @@
recover();
index = 0;
}
- if(baseExpression->getType().getQualifier() == EvqConstExpr)
+ if(baseExpression->getType().getQualifier() == EvqConstExpr && baseExpression->getAsConstantUnion()) // TODO: Qualifier check redundant?
{
if(baseExpression->isArray())
{
@@ -2693,11 +2654,6 @@
recover();
indexedExpression = baseExpression;
}
- else
- {
- indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
- EvqConstExpr, (unsigned char)(fieldString).size()));
- }
}
else
{
@@ -2708,41 +2664,6 @@
baseExpression->getQualifier() == EvqConstExpr ? EvqConstExpr : EvqTemporary, (unsigned char)vectorString.size()));
}
}
- else if(baseExpression->isMatrix())
- {
- TMatrixFields fields;
- if(!parseMatrixFields(fieldString, baseExpression->getNominalSize(), baseExpression->getSecondarySize(), fields, fieldLocation))
- {
- fields.wholeRow = false;
- fields.wholeCol = false;
- fields.row = 0;
- fields.col = 0;
- recover();
- }
-
- if(fields.wholeRow || fields.wholeCol)
- {
- error(dotLocation, " non-scalar fields not implemented yet", ".");
- recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setIConst(0);
- TIntermTyped *index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr),
- fieldLocation);
- indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
- indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),
- EvqTemporary, static_cast<unsigned char>(baseExpression->getNominalSize()),
- static_cast<unsigned char>(baseExpression->getSecondarySize())));
- }
- else
- {
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setIConst(fields.col * baseExpression->getSecondarySize() + fields.row);
- TIntermTyped *index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr),
- fieldLocation);
- indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation);
- indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision()));
- }
- }
else if(baseExpression->getBasicType() == EbtStruct)
{
bool fieldFound = false;
@@ -2840,13 +2761,13 @@
{
if(mShaderVersion < 300)
{
- error(dotLocation, " field selection requires structure, vector, or matrix on left hand side",
+ error(dotLocation, " field selection requires structure or vector on left hand side",
fieldString.c_str());
}
else
{
error(dotLocation,
- " field selection requires structure, vector, matrix, or interface block on left hand side",
+ " field selection requires structure, vector, or interface block on left hand side",
fieldString.c_str());
}
recover();
@@ -2902,7 +2823,7 @@
{
TLayoutQualifier qualifier;
- qualifier.location = -1;
+ qualifier.location = -1; // -1 isn't a valid location, it means the value isn't set. Negative values are checked lower in this function.
qualifier.matrixPacking = EmpUnspecified;
qualifier.blockStorage = EbsUnspecified;
@@ -3001,12 +2922,12 @@
recover();
}
- for(unsigned int i = 0; i < fieldList->size(); ++i)
+ for(const auto &field : *fieldList)
{
//
// Careful not to replace already known aspects of type, like array-ness
//
- TType *type = (*fieldList)[i]->type();
+ TType *type = field->type();
type->setBasicType(typeSpecifier.type);
type->setNominalSize(typeSpecifier.primarySize);
type->setSecondarySize(typeSpecifier.secondarySize);
@@ -3027,7 +2948,7 @@
type->setStruct(typeSpecifier.userDef->getStruct());
}
- if(structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i]))
+ if(structNestingErrorCheck(typeSpecifier.line, *field))
{
recover();
}
@@ -3054,7 +2975,7 @@
recover();
}
TVariable *userTypeDef = new TVariable(structName, *structureType, true);
- if(!symbolTable.declare(*userTypeDef))
+ if(!symbolTable.declare(userTypeDef))
{
error(nameLine, "redefinition", structName->c_str(), "struct");
recover();
@@ -3062,17 +2983,16 @@
}
// ensure we do not specify any storage qualifiers on the struct members
- for(unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
+ for(const auto &field : *fieldList)
{
- const TField &field = *(*fieldList)[typeListIndex];
- const TQualifier qualifier = field.type()->getQualifier();
+ const TQualifier qualifier = field->type()->getQualifier();
switch(qualifier)
{
case EvqGlobal:
case EvqTemporary:
break;
default:
- error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier));
+ error(field->line(), "invalid qualifier on struct member", getQualifierString(qualifier));
recover();
break;
}
@@ -3621,18 +3541,6 @@
else
{
arraySize = typedThis->getArraySize();
- if(typedThis->getAsSymbolNode() == nullptr)
- {
- // This code path can be hit with expressions like these:
- // (a = b).length()
- // (func()).length()
- // (int[3](0, 1, 2)).length()
- // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid expression.
- // It allows "An array name with the length method applied" in contrast to GLSL 4.4 spec section 5.9
- // which allows "An array, vector or matrix expression with the length method applied".
- error(loc, "length can only be called on array names, not on array expressions", "length");
- recover();
- }
}
unionArray->setIConst(arraySize);
callNode = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConstExpr), loc);
diff --git a/src/OpenGL/compiler/ParseHelper.h b/src/OpenGL/compiler/ParseHelper.h
index ea613eb..07abf0f 100644
--- a/src/OpenGL/compiler/ParseHelper.h
+++ b/src/OpenGL/compiler/ParseHelper.h
@@ -56,7 +56,7 @@
mDefaultBlockStorage(EbsShared),
mDiagnostics(is),
mDirectiveHandler(ext, mDiagnostics, mShaderVersion),
- mPreprocessor(&mDiagnostics, &mDirectiveHandler),
+ mPreprocessor(&mDiagnostics, &mDirectiveHandler, pp::PreprocessorSettings()),
mScanner(nullptr),
mUsesFragData(false),
mUsesFragColor(false) { }
@@ -112,7 +112,6 @@
const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol);
bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line);
- bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc &line);
bool reservedErrorCheck(const TSourceLoc &line, const TString& identifier);
void assignError(const TSourceLoc &line, const char* op, TString left, TString right);
@@ -149,7 +148,7 @@
void handleExtensionDirective(const TSourceLoc &line, const char* extName, const char* behavior);
const TPragma& pragma() const { return mDirectiveHandler.pragma(); }
- void handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value);
+ void handlePragmaDirective(const TSourceLoc &line, const char* name, const char* value, bool stdgl);
bool containsSampler(TType& type);
const TFunction* findFunction(const TSourceLoc &line, TFunction* pfnCall, bool *builtIn = 0);
diff --git a/src/OpenGL/compiler/PoolAlloc.cpp b/src/OpenGL/compiler/PoolAlloc.cpp
index f3d19eb..1235023 100644
--- a/src/OpenGL/compiler/PoolAlloc.cpp
+++ b/src/OpenGL/compiler/PoolAlloc.cpp
@@ -57,27 +57,16 @@
// is documented in PoolAlloc.h.
//
TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
- pageSize(growthIncrement),
- alignment(allocationAlignment),
+ alignment(allocationAlignment)
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ , pageSize(growthIncrement),
freeList(0),
inUseList(0),
numCalls(0),
totalBytes(0)
+#endif
{
//
- // Don't allow page sizes we know are smaller than all common
- // OS page sizes.
- //
- if (pageSize < 4*1024)
- pageSize = 4*1024;
-
- //
- // A large currentPageOffset indicates a new page needs to
- // be obtained to allocate memory.
- //
- currentPageOffset = pageSize;
-
- //
// Adjust alignment to be at least pointer aligned and
// power of 2.
//
@@ -91,6 +80,20 @@
alignment = a;
alignmentMask = a - 1;
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ //
+ // Don't allow page sizes we know are smaller than all common
+ // OS page sizes.
+ //
+ if (pageSize < 4*1024)
+ pageSize = 4*1024;
+
+ //
+ // A large currentPageOffset indicates a new page needs to
+ // be obtained to allocate memory.
+ //
+ currentPageOffset = pageSize;
+
//
// Align header skip
//
@@ -98,10 +101,14 @@
if (headerSkip < sizeof(tHeader)) {
headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
}
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ mStack.push_back({});
+#endif
}
TPoolAllocator::~TPoolAllocator()
{
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
while (inUseList) {
tHeader* next = inUseList->nextPage;
inUseList->~tHeader();
@@ -118,6 +125,14 @@
delete [] reinterpret_cast<char*>(freeList);
freeList = next;
}
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ for (auto& allocs : mStack) {
+ for (auto alloc : allocs) {
+ free(alloc);
+ }
+ }
+ mStack.clear();
+#endif
}
// Support MSVC++ 6.0
@@ -158,14 +173,18 @@
void TPoolAllocator::push()
{
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
tAllocState state = { currentPageOffset, inUseList };
- stack.push_back(state);
+ mStack.push_back(state);
//
// Indicate there is no current page to allocate from.
//
currentPageOffset = pageSize;
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ mStack.push_back({});
+#endif
}
//
@@ -177,11 +196,12 @@
//
void TPoolAllocator::pop()
{
- if (stack.size() < 1)
+ if (mStack.size() < 1)
return;
- tHeader* page = stack.back().page;
- currentPageOffset = stack.back().offset;
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ tHeader* page = mStack.back().page;
+ currentPageOffset = mStack.back().offset;
while (inUseList != page) {
// invoke destructor to free allocation list
@@ -197,7 +217,13 @@
inUseList = nextInUse;
}
- stack.pop_back();
+ mStack.pop_back();
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ for (auto alloc : mStack.back()) {
+ free(alloc);
+ }
+ mStack.pop_back();
+#endif
}
//
@@ -206,12 +232,13 @@
//
void TPoolAllocator::popAll()
{
- while (stack.size() > 0)
+ while (mStack.size() > 0)
pop();
}
void* TPoolAllocator::allocate(size_t numBytes)
{
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
//
// Just keep some interesting statistics.
//
@@ -288,6 +315,14 @@
currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
return initializeAllocation(inUseList, ret, numBytes);
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ void *alloc = malloc(numBytes + alignmentMask);
+ mStack.back().push_back(alloc);
+
+ intptr_t intAlloc = reinterpret_cast<intptr_t>(alloc);
+ intAlloc = (intAlloc + alignmentMask) & ~alignmentMask;
+ return reinterpret_cast<void *>(intAlloc);
+#endif
}
diff --git a/src/OpenGL/compiler/PoolAlloc.h b/src/OpenGL/compiler/PoolAlloc.h
index 1aca1c9..d645a04 100644
--- a/src/OpenGL/compiler/PoolAlloc.h
+++ b/src/OpenGL/compiler/PoolAlloc.h
@@ -160,7 +160,12 @@
// by calling pop(), and to not have to solve memory leak problems.
//
-protected:
+private:
+ size_t alignment; // all returned allocations will be aligned at
+ // this granularity, which will be a power of 2
+ size_t alignmentMask;
+
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
friend struct tHeader;
struct tHeader {
@@ -203,20 +208,21 @@
}
size_t pageSize; // granularity of allocation from the OS
- size_t alignment; // all returned allocations will be aligned at
- // this granularity, which will be a power of 2
- size_t alignmentMask;
size_t headerSkip; // amount of memory to skip to make room for the
// header (basically, size of header, rounded
// up to make it aligned
size_t currentPageOffset; // next offset in top of inUseList to allocate from
tHeader* freeList; // list of popped memory
tHeader* inUseList; // list of all memory currently being used
- tAllocStack stack; // stack of where to allocate from, to partition pool
+ tAllocStack mStack; // stack of where to allocate from, to partition pool
int numCalls; // just an interesting statistic
size_t totalBytes; // just an interesting statistic
-private:
+
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ std::vector<std::vector<void *>> mStack;
+#endif
+
TPoolAllocator& operator=(const TPoolAllocator&); // dont allow assignment operator
TPoolAllocator(const TPoolAllocator&); // dont allow default copy constructor
};
diff --git a/src/OpenGL/compiler/SymbolTable.cpp b/src/OpenGL/compiler/SymbolTable.cpp
index b2e48e8..3e6cae8 100644
--- a/src/OpenGL/compiler/SymbolTable.cpp
+++ b/src/OpenGL/compiler/SymbolTable.cpp
@@ -27,21 +27,20 @@
#include <limits.h>
#include <algorithm>
-#if defined(_MSC_VER) && MSC_VER < 1900
-#define snprintf _snprintf
+#if defined(_MSC_VER) && MSC_VER < 1900
+#define snprintf _snprintf
#endif
int TSymbolTableLevel::uniqueId = 0;
TType::TType(const TPublicType &p) :
- type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(p.invariant), layoutQualifier(p.layoutQualifier),
+ type(p.type), precision(p.precision), qualifier(p.qualifier),
primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), maxArraySize(0),
- arrayInformationType(0), interfaceBlock(0), structure(0), deepestStructNesting(0), mangled(0)
+ arrayInformationType(0), interfaceBlock(0), layoutQualifier(p.layoutQualifier), structure(0), mangled(0)
{
if (p.userDef)
{
structure = p.userDef->getStruct();
- computeDeepestStructNesting();
}
}
@@ -64,6 +63,7 @@
case EbtSampler3D: mangledName += "s3"; break;
case EbtSamplerCube: mangledName += "sC"; break;
case EbtSampler2DArray: mangledName += "s2a"; break;
+ case EbtSampler2DRect: mangledName += "s2r"; break;
case EbtSamplerExternalOES: mangledName += "sext"; break;
case EbtISampler2D: mangledName += "is2"; break;
case EbtISampler3D: mangledName += "is3"; break;
@@ -105,16 +105,11 @@
return getStruct()->objectSize();
}
-void TType::computeDeepestStructNesting()
-{
- deepestStructNesting = structure ? structure->deepestNesting() : 0;
-}
-
bool TStructure::containsArrays() const
{
- for(size_t i = 0; i < mFields->size(); ++i)
+ for(const auto& field : *mFields)
{
- const TType *fieldType = (*mFields)[i]->type();
+ const TType *fieldType = field->type();
if(fieldType->isArray() || fieldType->isStructureContainingArrays())
return true;
}
@@ -123,9 +118,9 @@
bool TStructure::containsType(TBasicType type) const
{
- for(size_t i = 0; i < mFields->size(); ++i)
+ for(const auto& field : *mFields)
{
- const TType *fieldType = (*mFields)[i]->type();
+ const TType *fieldType = field->type();
if(fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
return true;
}
@@ -134,23 +129,31 @@
bool TStructure::containsSamplers() const
{
- for(size_t i = 0; i < mFields->size(); ++i)
+ for(const auto& field : *mFields)
{
- const TType *fieldType = (*mFields)[i]->type();
+ const TType *fieldType = field->type();
if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
return true;
}
return false;
}
+void TStructure::setMatrixPackingIfUnspecified(TLayoutMatrixPacking matrixPacking)
+{
+ for(auto& field : *mFields)
+ {
+ field->type()->setMatrixPackingIfUnspecified(matrixPacking);
+ }
+}
+
TString TFieldListCollection::buildMangledName() const
{
TString mangledName(mangledNamePrefix());
mangledName += *mName;
- for(size_t i = 0; i < mFields->size(); ++i)
+ for(const auto& field : *mFields)
{
mangledName += '-';
- mangledName += (*mFields)[i]->type()->getMangledName();
+ mangledName += field->type()->getMangledName();
}
return mangledName;
}
@@ -158,9 +161,9 @@
size_t TFieldListCollection::calculateObjectSize() const
{
size_t size = 0;
- for(size_t i = 0; i < mFields->size(); ++i)
+ for(const auto& field : *mFields)
{
- size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
+ size_t fieldSize = field->type()->getObjectSize();
if(fieldSize > INT_MAX - size)
size = INT_MAX;
else
@@ -172,8 +175,8 @@
int TStructure::calculateDeepestNesting() const
{
int maxNesting = 0;
- for(size_t i = 0; i < mFields->size(); ++i)
- maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
+ for(const auto& field : *mFields)
+ maxNesting = std::max(maxNesting, field->type()->getDeepestStructNesting());
return 1 + maxNesting;
}
@@ -195,6 +198,35 @@
delete (*it).second;
}
+bool TSymbolTableLevel::insert(TSymbol *symbol)
+{
+ symbol->setUniqueId(nextUniqueId());
+
+ // returning true means symbol was added to the table
+ tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
+
+ return result.second;
+}
+
+bool TSymbolTableLevel::insertUnmangled(TFunction *function)
+{
+ function->setUniqueId(nextUniqueId());
+
+ // returning true means symbol was added to the table
+ tInsertResult result = level.insert(tLevelPair(function->getName(), function));
+
+ return result.second;
+}
+
+TSymbol *TSymbolTableLevel::find(const TString &name) const
+{
+ tLevel::const_iterator it = level.find(name);
+ if (it == level.end())
+ return 0;
+ else
+ return (*it).second;
+}
+
TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
{
int level = currentLevel();
diff --git a/src/OpenGL/compiler/SymbolTable.h b/src/OpenGL/compiler/SymbolTable.h
index c4fdbfe..3466f2f 100644
--- a/src/OpenGL/compiler/SymbolTable.h
+++ b/src/OpenGL/compiler/SymbolTable.h
@@ -206,27 +206,12 @@
TSymbolTableLevel() { }
~TSymbolTableLevel();
- bool insert(TSymbol &symbol)
- {
- symbol.setUniqueId(nextUniqueId());
+ bool insert(TSymbol *symbol);
- //
- // returning true means symbol was added to the table
- //
- tInsertResult result;
- result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
+ // Insert a function using its unmangled name as the key.
+ bool insertUnmangled(TFunction *function);
- return result.second;
- }
-
- TSymbol* find(const TString& name) const
- {
- tLevel::const_iterator it = level.find(name);
- if (it == level.end())
- return 0;
- else
- return (*it).second;
- }
+ TSymbol *find(const TString &name) const;
static int nextUniqueId()
{
@@ -348,12 +333,12 @@
precisionStack.pop_back();
}
- bool declare(TSymbol &symbol)
+ bool declare(TSymbol *symbol)
{
return insert(currentLevel(), symbol);
}
- bool insert(ESymbolLevel level, TSymbol &symbol)
+ bool insert(ESymbolLevel level, TSymbol *symbol)
{
return table[level]->insert(symbol);
}
@@ -362,7 +347,7 @@
{
TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConstExpr, 1));
constant->getConstPointer()->setIConst(value);
- return insert(level, *constant);
+ return insert(level, constant);
}
void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
@@ -448,7 +433,7 @@
}
ASSERT(hasUnmangledBuiltIn(name));
- insert(level, *function);
+ insert(level, function);
}
}
diff --git a/src/OpenGL/compiler/Types.h b/src/OpenGL/compiler/Types.h
index d4d98d0..5318e39 100644
--- a/src/OpenGL/compiler/Types.h
+++ b/src/OpenGL/compiler/Types.h
@@ -137,6 +137,8 @@
bool equals(const TStructure &other) const;
+ void setMatrixPackingIfUnspecified(TLayoutMatrixPacking matrixPacking);
+
void setUniqueId(int uniqueId)
{
mUniqueId = uniqueId;
@@ -238,36 +240,38 @@
{
public:
POOL_ALLOCATOR_NEW_DELETE();
- TType() {}
+
TType(TBasicType t, int s0 = 1, int s1 = 1) :
- type(t), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false), layoutQualifier(TLayoutQualifier::create()),
- primarySize(s0), secondarySize(s1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
- structure(0), deepestStructNesting(0), mangled(0)
+ type(t), precision(EbpUndefined), qualifier(EvqGlobal),
+ primarySize(s0), secondarySize(s1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0), layoutQualifier(TLayoutQualifier::create()),
+ structure(0), mangled(0)
{
}
+
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s0 = 1, int s1 = 1, bool a = false) :
- type(t), precision(p), qualifier(q), invariant(false), layoutQualifier(TLayoutQualifier::create()),
- primarySize(s0), secondarySize(s1), array(a), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
- structure(0), deepestStructNesting(0), mangled(0)
+ type(t), precision(p), qualifier(q),
+ primarySize(s0), secondarySize(s1), array(a), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0), layoutQualifier(TLayoutQualifier::create()),
+ structure(0), mangled(0)
{
}
- explicit TType(const TPublicType &p);
+
TType(TStructure* userDef, TPrecision p = EbpUndefined) :
- type(EbtStruct), precision(p), qualifier(EvqTemporary), invariant(false), layoutQualifier(TLayoutQualifier::create()),
- primarySize(1), secondarySize(1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0),
- structure(userDef), deepestStructNesting(0), mangled(0)
+ type(EbtStruct), precision(p), qualifier(EvqTemporary),
+ primarySize(1), secondarySize(1), array(false), arraySize(0), maxArraySize(0), arrayInformationType(0), interfaceBlock(0), layoutQualifier(TLayoutQualifier::create()),
+ structure(userDef), mangled(0)
{
}
TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn,
TLayoutQualifier layoutQualifierIn, int arraySizeIn)
: type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn),
- invariant(false), layoutQualifier(layoutQualifierIn),
primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn), maxArraySize(0), arrayInformationType(0),
- interfaceBlock(interfaceBlockIn), structure(0), deepestStructNesting(0), mangled(0)
+ interfaceBlock(interfaceBlockIn), layoutQualifier(layoutQualifierIn), structure(0), mangled(0)
{
}
+ explicit TType(const TPublicType &p);
+
TBasicType getBasicType() const { return type; }
void setBasicType(TBasicType t) { type = t; }
@@ -277,11 +281,24 @@
TQualifier getQualifier() const { return qualifier; }
void setQualifier(TQualifier q) { qualifier = q; }
- bool isInvariant() const { return invariant; }
-
TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
+ void setMatrixPackingIfUnspecified(TLayoutMatrixPacking matrixPacking)
+ {
+ if(isStruct())
+ {
+ // If the structure's matrix packing is specified, it overrules the block's matrix packing
+ structure->setMatrixPackingIfUnspecified((layoutQualifier.matrixPacking == EmpUnspecified) ?
+ matrixPacking : layoutQualifier.matrixPacking);
+ }
+ // If the member's matrix packing is specified, it overrules any higher level matrix packing
+ if(layoutQualifier.matrixPacking == EmpUnspecified)
+ {
+ layoutQualifier.matrixPacking = matrixPacking;
+ }
+ }
+
// One-dimensional size of single instance type
int getNominalSize() const { return primarySize; }
void setNominalSize(int s) { primarySize = s; }
@@ -318,6 +335,24 @@
}
}
+ int samplerRegisterCount() const
+ {
+ if(structure)
+ {
+ int registerCount = 0;
+
+ const TFieldList& fields = isInterfaceBlock() ? interfaceBlock->fields() : structure->fields();
+ for(size_t i = 0; i < fields.size(); i++)
+ {
+ registerCount += fields[i]->type()->totalSamplerRegisterCount();
+ }
+
+ return registerCount;
+ }
+
+ return IsSampler(getBasicType()) ? 1 : 0;
+ }
+
int elementRegisterCount() const
{
if(structure || isInterfaceBlock())
@@ -360,6 +395,18 @@
return totalRegisterCount();
}
+ int totalSamplerRegisterCount() const
+ {
+ if(array)
+ {
+ return arraySize * samplerRegisterCount();
+ }
+ else
+ {
+ return samplerRegisterCount();
+ }
+ }
+
int totalRegisterCount() const
{
if(array)
@@ -403,7 +450,7 @@
bool isScalarInt() const { return isScalar() && IsInteger(type); }
TStructure* getStruct() const { return structure; }
- void setStruct(TStructure* s) { structure = s; computeDeepestStructNesting(); }
+ void setStruct(TStructure* s) { structure = s; }
TString& getMangledName() {
if (!mangled) {
@@ -483,27 +530,24 @@
protected:
void buildMangledName(TString&);
size_t getStructSize() const;
- void computeDeepestStructNesting();
- TBasicType type;
- TPrecision precision;
- TQualifier qualifier;
- bool invariant;
+ TBasicType type = EbtVoid;
+ TPrecision precision = EbpUndefined;
+ TQualifier qualifier = EvqTemporary;
+ unsigned char primarySize = 0; // size of vector or matrix, not size of array
+ unsigned char secondarySize = 0; // 1 for vectors, > 1 for matrices
+ bool array = false;
+ int arraySize = 0;
+ int maxArraySize = 0;
+ TType *arrayInformationType = nullptr;
+
+ // null unless this is an interface block, or interface block member variable
+ TInterfaceBlock *interfaceBlock = nullptr;
TLayoutQualifier layoutQualifier;
- unsigned char primarySize; // size of vector or matrix, not size of array
- unsigned char secondarySize; // secondarySize: 1 for vectors, >1 for matrices
- bool array;
- int arraySize;
- int maxArraySize;
- TType *arrayInformationType;
- // 0 unless this is an interface block, or interface block member variable
- TInterfaceBlock *interfaceBlock;
+ TStructure *structure = nullptr; // null unless this is a struct
- TStructure *structure; // 0 unless this is a struct
- int deepestStructNesting;
-
- TString *mangled;
+ TString *mangled = nullptr;
};
//
diff --git a/src/OpenGL/compiler/glslang.l b/src/OpenGL/compiler/glslang.l
index 663db3b..fdc3977 100644
--- a/src/OpenGL/compiler/glslang.l
+++ b/src/OpenGL/compiler/glslang.l
@@ -171,6 +171,7 @@
"sampler2D" { context->lexAfterType = true; return SAMPLER2D; }
"samplerCube" { context->lexAfterType = true; return SAMPLERCUBE; }
+"sampler2DRect" { context->lexAfterType = true; return SAMPLER2DRECT; }
"samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
"sampler3D" { context->lexAfterType = true; return SAMPLER3D; }
"sampler3DRect" { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); }
@@ -312,7 +313,6 @@
"sampler1D" |
"sampler1DShadow" |
-"sampler2DRect" |
"sampler2DRectShadow" |
"sizeof" |
@@ -492,7 +492,7 @@
return 0;
}
- if (!atoi_clamp(yytext, &(yylval->lex.i)))
+ if (!atou_clamp(yytext, &(yylval->lex.u)))
yyextra->warning(*yylloc, "Integer overflow", yytext, "");
return UINTCONSTANT;
diff --git a/src/OpenGL/compiler/glslang.y b/src/OpenGL/compiler/glslang.y
index c7e8f28..cd0daff 100644
--- a/src/OpenGL/compiler/glslang.y
+++ b/src/OpenGL/compiler/glslang.y
@@ -233,8 +233,9 @@
// don't delete $1.string, it's used by error recovery, and the pool
// pop will reclaim the memory
+ // Constants which aren't indexable arrays can be propagated by value.
ConstantUnion *constArray = variable->getConstPointer();
- if (constArray) {
+ if (constArray && variable->getType().getArraySize() <= 1) {
TType t(variable->getType());
$$ = context->intermediate.addConstantUnion(constArray, t, @1);
} else
@@ -1221,7 +1222,7 @@
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerCube, qual, @1);
}
- | SAMPLER_EXTERNAL_OES {
+ | SAMPLER_EXTERNAL_OES {
if (!context->supportsExtension("GL_OES_EGL_image_external")) {
context->error(@1, "unsupported type", "samplerExternalOES", "");
context->recover();
@@ -1230,6 +1231,15 @@
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerExternalOES, qual, @1);
}
+ | SAMPLER2DRECT {
+ if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
+ context->error(@1, "unsupported type", "sampler2DRect", "");
+ context->recover();
+ }
+ FRAG_VERT_ONLY("sampler2DRect", @1);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.setBasic(EbtSampler2DRect, qual, @1);
+ }
| SAMPLER3D {
FRAG_VERT_ONLY("sampler3D", @1);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
diff --git a/src/OpenGL/compiler/glslang_lex.cpp b/src/OpenGL/compiler/glslang_lex.cpp
index 2316c51..0cf1555 100644
--- a/src/OpenGL/compiler/glslang_lex.cpp
+++ b/src/OpenGL/compiler/glslang_lex.cpp
@@ -29,20 +29,84 @@
-#line 33 "./glslang_lex.cpp"
-
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
+
+
+
+
+
+
+
+
+
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 0
+#define YY_FLEX_SUBMINOR_VERSION 4
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef yyget_lval
+#define yyget_lval_ALREADY_DEFINED
+#else
+#define yyget_lval yyget_lval
+#endif
+
+
+#ifdef yyset_lval
+#define yyset_lval_ALREADY_DEFINED
+#else
+#define yyset_lval yyset_lval
+#endif
+
+
+
+
+
+#ifdef yyget_lloc
+#define yyget_lloc_ALREADY_DEFINED
+#else
+#define yyget_lloc yyget_lloc
+#endif
+
+
+#ifdef yyset_lloc
+#define yyset_lloc_ALREADY_DEFINED
+#else
+#define yyset_lloc yyset_lloc
+#endif
+
+
+
+
+
+
+
+
+
+
+
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
@@ -113,40 +177,38 @@
#define UINT32_MAX (4294967295U)
#endif
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
-#ifdef __cplusplus
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
+/* begin standard C++ headers. */
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
#else
-#define yyconst
+#define yynoreturn
#endif
/* Returned upon end-of-file. */
#define YY_NULL 0
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
*/
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+
+
+
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -154,6 +216,22 @@
typedef void* yyscan_t;
#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/* For convenience, these vars (plus the bison vars far below)
are macros in the reentrant scanner. */
#define yyin yyg->yyin_r
@@ -165,27 +243,36 @@
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
#define yy_flex_debug yyg->yy_flex_debug_r
+
+
+
+
+
+
+
+
+
+
+
+
/* Enter a start condition. This macro really ought to take a parameter,
* but we do it the disgusting crufty way forced on us by the ()-less
* definition of BEGIN.
*/
#define BEGIN yyg->yy_start = 1 + 2 *
-
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
#define YY_START ((yyg->yy_start - 1) / 2)
#define YYSTATE YY_START
-
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
-
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
#define YY_END_OF_BUFFER_CHAR 0
+
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
#ifdef __ia64__
@@ -199,10 +286,13 @@
#endif /* __ia64__ */
#endif
+
/* The state buf must be large enough to hold one state per character in the main buffer.
*/
#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
@@ -213,13 +303,16 @@
typedef size_t yy_size_t;
#endif
+
+
+
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
-
+
/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
* access to the local variable yy_act. Since yyless() is a macro, it would break
- * existing scanners that call yyless() from OUTSIDE yylex.
+ * existing scanners that call yyless() from OUTSIDE yylex.
* One obvious solution it to make yy_act a global. I tried that, and saw
* a 5% performance hit in a non-yylineno scanner, because yy_act is
* normally declared as a register variable-- so it is not worth it.
@@ -252,27 +345,29 @@
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
-
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
FILE *yy_input_file;
+
+
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
- yy_size_t yy_buf_size;
+ int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- yy_size_t yy_n_chars;
+ int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -295,7 +390,8 @@
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -320,6 +416,9 @@
};
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+
+
/* We provide macros for accessing buffer states in case in the
* future we want to put the buffer states in a more general
* "scanner state".
@@ -329,87 +428,95 @@
#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
: NULL)
-
/* Same as previous macro, but useful when we know that the buffer stack is not
* NULL or when we need an lvalue. For internal use only.
*/
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-void yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void yypop_buffer_state (yyscan_t yyscanner );
-static void yyensure_buffer_stack (yyscan_t yyscanner );
-static void yy_load_buffer_state (yyscan_t yyscanner );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
-void *yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void yyfree (void * ,yyscan_t yyscanner );
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
+
+
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
+
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+
+
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
+
#define yy_new_buffer yy_create_buffer
-
#define yy_set_interactive(is_interactive) \
{ \
if ( ! YY_CURRENT_BUFFER ){ \
yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
-
#define yy_set_bol(at_bol) \
{ \
if ( ! YY_CURRENT_BUFFER ){\
yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
-
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
/* Begin user sect3 */
#define yywrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
+typedef flex_uint8_t YY_CHAR;
-typedef unsigned char YY_CHAR;
typedef int yy_state_type;
#define yytext_ptr yytext_r
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-#if defined(__GNUC__) && __GNUC__ >= 3
-__attribute__((__noreturn__))
-#endif
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+
+
+
+
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
+
+
+
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
+ yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-
#define YY_NUM_RULES 239
#define YY_END_OF_BUFFER 240
/* This struct is not used in this scanner,
@@ -419,7 +526,7 @@
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[821] =
+static const flex_int16_t yy_accept[821] =
{ 0,
0, 0, 0, 0, 0, 0, 240, 238, 237, 237,
222, 228, 233, 217, 218, 226, 225, 214, 223, 221,
@@ -438,7 +545,7 @@
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 199, 203, 235, 0, 189, 185, 0, 188,
- 182, 0, 184, 178, 195, 196, 177, 135, 177, 177,
+ 182, 0, 184, 178, 195, 196, 177, 136, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 13, 177, 177, 177, 177, 177, 177, 177, 177,
@@ -450,70 +557,70 @@
177, 177, 177, 177, 177, 177, 177, 177, 177, 0,
186, 0, 185, 187, 181, 177, 177, 177, 30, 177,
177, 18, 174, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 16, 138, 177, 177, 177, 177, 21,
- 177, 177, 142, 154, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 151, 4, 35, 36,
+ 177, 177, 177, 16, 139, 177, 177, 177, 177, 21,
+ 177, 177, 143, 155, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 152, 4, 35, 36,
37, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 141, 31, 177, 177, 28,
+ 177, 177, 177, 177, 177, 142, 31, 177, 177, 28,
177, 177, 177, 177, 177, 177, 177, 47, 48, 49,
29, 177, 177, 177, 177, 177, 177, 10, 56, 57,
- 58, 177, 136, 177, 177, 7, 177, 177, 177, 177,
- 163, 164, 165, 177, 32, 177, 155, 26, 166, 167,
- 168, 2, 160, 161, 162, 177, 177, 177, 25, 158,
+ 58, 177, 137, 177, 177, 7, 177, 177, 177, 177,
+ 164, 165, 166, 177, 32, 177, 156, 26, 167, 168,
+ 169, 2, 161, 162, 163, 177, 177, 177, 25, 159,
177, 177, 177, 50, 51, 52, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 85, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 86, 177, 177,
- 177, 177, 177, 177, 177, 152, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 137, 177, 177,
- 176, 53, 54, 55, 177, 177, 14, 177, 90, 177,
- 177, 177, 177, 88, 177, 177, 177, 153, 148, 91,
- 177, 177, 177, 177, 177, 177, 143, 177, 177, 177,
- 77, 38, 41, 43, 42, 39, 45, 44, 46, 40,
- 177, 177, 177, 177, 159, 134, 177, 177, 146, 177,
- 177, 177, 34, 86, 173, 22, 147, 76, 177, 157,
+ 177, 177, 177, 177, 177, 153, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 138, 177, 177,
+ 176, 53, 54, 55, 177, 177, 14, 177, 91, 177,
+ 177, 177, 177, 89, 177, 177, 177, 154, 149, 92,
+ 177, 177, 177, 177, 177, 177, 144, 177, 177, 177,
+ 78, 38, 41, 43, 42, 39, 45, 44, 46, 40,
+ 177, 177, 177, 177, 160, 135, 177, 177, 147, 177,
+ 177, 177, 34, 87, 173, 22, 148, 77, 177, 158,
17, 177, 177, 177, 177, 177, 177, 177, 177, 177,
177, 177, 177, 177, 177, 19, 33, 177, 177, 177,
- 177, 177, 177, 92, 93, 94, 177, 177, 177, 177,
+ 177, 177, 177, 93, 94, 95, 177, 177, 177, 177,
177, 3, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 139, 177, 177, 177, 177, 177, 8,
- 177, 177, 9, 177, 177, 177, 177, 20, 78, 11,
- 149, 96, 97, 98, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 144, 177, 177, 177,
- 80, 82, 79, 177, 177, 177, 177, 177, 177, 177,
- 140, 100, 101, 102, 177, 177, 156, 177, 145, 177,
+ 177, 177, 177, 140, 177, 177, 177, 177, 177, 8,
+ 177, 177, 9, 177, 177, 177, 177, 20, 79, 11,
+ 150, 97, 98, 99, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 145, 177, 177, 177,
+ 81, 83, 80, 177, 177, 177, 177, 177, 177, 177,
+ 141, 101, 102, 103, 177, 177, 157, 177, 146, 177,
177, 6, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 95, 150, 1, 177, 177, 177, 177, 177, 175,
+ 177, 96, 151, 1, 177, 177, 177, 177, 177, 175,
- 177, 89, 5, 169, 59, 62, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177, 177, 81,
- 177, 177, 177, 177, 99, 177, 177, 177, 177, 177,
- 119, 65, 66, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 87, 177, 177, 177,
- 103, 121, 69, 70, 177, 177, 83, 177, 177, 177,
- 177, 177, 177, 177, 114, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 128, 177, 177, 177, 177,
+ 177, 90, 5, 170, 59, 63, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 82,
+ 177, 177, 177, 177, 100, 177, 177, 177, 177, 177,
+ 120, 66, 67, 177, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 88, 177, 177, 177,
+ 104, 122, 70, 71, 177, 177, 84, 177, 177, 177,
+ 177, 177, 177, 177, 115, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 129, 177, 177, 177, 177,
60, 177, 177, 177, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 115, 104, 177, 105, 177, 177, 177,
+ 177, 177, 177, 116, 105, 177, 106, 177, 177, 177,
- 129, 177, 177, 67, 177, 177, 177, 177, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 116, 177, 177,
- 130, 177, 177, 71, 106, 107, 177, 110, 177, 111,
- 177, 177, 177, 177, 177, 84, 177, 177, 177, 177,
- 171, 177, 63, 125, 177, 177, 108, 109, 177, 177,
- 177, 177, 177, 177, 177, 177, 177, 177, 123, 126,
- 117, 177, 64, 177, 177, 177, 177, 177, 177, 177,
- 177, 124, 127, 177, 177, 120, 68, 177, 177, 170,
- 177, 177, 177, 73, 177, 177, 122, 72, 177, 177,
- 177, 177, 177, 177, 131, 177, 177, 177, 177, 177,
+ 130, 177, 177, 68, 177, 177, 177, 177, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 117, 177, 177,
+ 131, 177, 177, 72, 107, 108, 177, 111, 177, 112,
+ 177, 177, 177, 177, 177, 85, 177, 177, 177, 177,
+ 61, 177, 64, 126, 177, 177, 109, 110, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 124, 127,
+ 118, 177, 65, 177, 177, 177, 177, 177, 177, 177,
+ 177, 125, 128, 177, 177, 121, 69, 177, 177, 171,
+ 177, 177, 177, 74, 177, 177, 123, 73, 177, 177,
+ 177, 177, 177, 177, 132, 177, 177, 177, 177, 177,
- 177, 132, 177, 177, 177, 74, 177, 133, 112, 113,
- 177, 177, 177, 61, 177, 177, 172, 118, 75, 0
+ 177, 133, 177, 177, 177, 75, 177, 134, 113, 114,
+ 177, 177, 177, 62, 177, 177, 172, 119, 76, 0
} ;
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
@@ -545,7 +652,7 @@
1, 1, 1, 1, 1
} ;
-static yyconst YY_CHAR yy_meta[73] =
+static const YY_CHAR yy_meta[73] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
@@ -557,7 +664,7 @@
1, 1
} ;
-static yyconst flex_uint16_t yy_base[827] =
+static const flex_int16_t yy_base[827] =
{ 0,
0, 0, 1019, 1018, 72, 0, 1020, 1023, 1023, 1023,
994, 120, 141, 1023, 1023, 993, 138, 1023, 137, 135,
@@ -652,7 +759,7 @@
509, 512, 515, 518, 519, 520
} ;
-static yyconst flex_int16_t yy_def[827] =
+static const flex_int16_t yy_def[827] =
{ 0,
820, 1, 821, 821, 820, 5, 820, 820, 820, 820,
820, 820, 820, 820, 820, 820, 820, 820, 820, 820,
@@ -747,7 +854,7 @@
820, 820, 820, 820, 820, 820
} ;
-static yyconst flex_uint16_t yy_nxt[1096] =
+static const flex_int16_t yy_nxt[1096] =
{ 0,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 23, 23, 23, 23,
@@ -872,7 +979,7 @@
} ;
-static yyconst flex_int16_t yy_chk[1096] =
+static const flex_int16_t yy_chk[1096] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -997,8 +1104,9 @@
} ;
+
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[240] =
+static const flex_int32_t yy_rule_can_match_eol[240] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1073,12 +1181,23 @@
static int float_constant(yyscan_t yyscanner);
static int floatsuffix_check(TParseContext* context);
+
+
+
#define INITIAL 0
#define COMMENT 1
#define FIELDS 2
+
+
+
+
+
#define YY_EXTRA_TYPE TParseContext*
+
+
+
/* Holds the entire state of the reentrant scanner. */
struct yyguts_t
{
@@ -1092,8 +1211,8 @@
size_t yy_buffer_stack_max; /**< capacity of stack. */
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
- yy_size_t yy_n_chars;
- yy_size_t yyleng_r;
+ int yy_n_chars;
+ int yyleng_r;
char *yy_c_buf_p;
int yy_init;
int yy_start;
@@ -1107,78 +1226,141 @@
int yylineno_r;
int yy_flex_debug_r;
+
+
+
char *yytext_r;
int yy_more_flag;
int yy_more_len;
+
+
YYSTYPE * yylval_r;
+
+
YYLTYPE * yylloc_r;
+
}; /* end struct yyguts_t */
-static int yy_init_globals (yyscan_t yyscanner );
+
+
+static int yy_init_globals ( yyscan_t yyscanner );
+
+
+
+
+
/* This must go here because YYSTYPE and YYLTYPE are included
* from bison output in section 1.*/
# define yylval yyg->yylval_r
+
+
# define yylloc yyg->yylloc_r
+
+
int yylex_init (yyscan_t* scanner);
-int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+
+
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int yylex_destroy (yyscan_t yyscanner );
-int yyget_debug (yyscan_t yyscanner );
+int yylex_destroy ( yyscan_t yyscanner );
-void yyset_debug (int debug_flag ,yyscan_t yyscanner );
-YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
-void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+int yyget_debug ( yyscan_t yyscanner );
-FILE *yyget_in (yyscan_t yyscanner );
-void yyset_in (FILE * _in_str ,yyscan_t yyscanner );
-FILE *yyget_out (yyscan_t yyscanner );
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
-void yyset_out (FILE * _out_str ,yyscan_t yyscanner );
-yy_size_t yyget_leng (yyscan_t yyscanner );
-char *yyget_text (yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
-int yyget_lineno (yyscan_t yyscanner );
-void yyset_lineno (int _line_number ,yyscan_t yyscanner );
-int yyget_column (yyscan_t yyscanner );
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
-void yyset_column (int _column_no ,yyscan_t yyscanner );
-YYSTYPE * yyget_lval (yyscan_t yyscanner );
-void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+FILE *yyget_in ( yyscan_t yyscanner );
- YYLTYPE *yyget_lloc (yyscan_t yyscanner );
+
+
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
+
+
+
+FILE *yyget_out ( yyscan_t yyscanner );
+
+
+
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
+
+
+
+ int yyget_leng ( yyscan_t yyscanner );
+
+
+
+char *yyget_text ( yyscan_t yyscanner );
+
+
+
+int yyget_lineno ( yyscan_t yyscanner );
+
+
+
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
+
+
+
+
+int yyget_column ( yyscan_t yyscanner );
+
+
+
+
+
+void yyset_column ( int _column_no , yyscan_t yyscanner );
+
+
+
+
+YYSTYPE * yyget_lval ( yyscan_t yyscanner );
+
+
+void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
+
+
- void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+ YYLTYPE *yyget_lloc ( yyscan_t yyscanner );
+
+
+ void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner );
+
+
+
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int yywrap (yyscan_t yyscanner );
+extern "C" int yywrap ( yyscan_t yyscanner );
#else
-extern int yywrap (yyscan_t yyscanner );
+extern int yywrap ( yyscan_t yyscanner );
#endif
#endif
@@ -1186,24 +1368,31 @@
#endif
+
#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
-
#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
+static int yyinput ( yyscan_t yyscanner );
#else
-static int input (yyscan_t yyscanner );
+static int input ( yyscan_t yyscanner );
#endif
#endif
+
+
+
+
+
+
+
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#ifdef __ia64__
@@ -1214,14 +1403,17 @@
#endif /* __ia64__ */
#endif
+
/* Copy whatever the last rule matched to the standard output. */
#ifndef ECHO
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
#endif
+
+
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
* is returned in "result".
*/
@@ -1230,7 +1422,7 @@
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- size_t n; \
+ int n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -1243,7 +1435,7 @@
else \
{ \
errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
@@ -1258,6 +1450,8 @@
#endif
+
+
/* No semi-colon after return; correct usage is to write "yyterminate();" -
* we don't want an extra ';' after the "return" because that will cause
* some compilers to complain about unreachable statements.
@@ -1266,31 +1460,54 @@
#define yyterminate() return YY_NULL
#endif
+
/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif
+
/* Report a fatal error. */
#ifndef YY_FATAL_ERROR
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
#endif
+
+
/* end tables serialization structures and prototypes */
+
+
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
extern int yylex \
- (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner);
#define YY_DECL int yylex \
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
#endif /* !YY_DECL */
+
/* Code executed at the beginning of each rule, after yytext and yyleng
* have been set up.
*/
@@ -1298,14 +1515,19 @@
#define YY_USER_ACTION
#endif
+
+
/* Code executed at the end of each rule. */
#ifndef YY_BREAK
#define YY_BREAK /*LINTED*/break;
#endif
+
+
#define YY_RULE_SETUP \
YY_USER_ACTION
+
/** The main scanner function which does all the work.
*/
YY_DECL
@@ -1315,10 +1537,16 @@
int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+
+
yylval = yylval_param;
+
+
yylloc = yylloc_param;
+
if ( !yyg->yy_init )
{
yyg->yy_init = 1;
@@ -1327,6 +1555,8 @@
YY_USER_INIT;
#endif
+
+
if ( ! yyg->yy_start )
yyg->yy_start = 1; /* first start state */
@@ -1339,16 +1569,20 @@
if ( ! YY_CURRENT_BUFFER ) {
yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
{
+
+
TParseContext* context = yyextra;
+
+
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
yy_cp = yyg->yy_c_buf_p;
@@ -1375,9 +1609,9 @@
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 821 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
while ( yy_current_state != 820 );
@@ -1389,20 +1623,23 @@
YY_DO_BEFORE_ACTION;
+
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
{
- yy_size_t yyl;
+ int yyl;
for ( yyl = 0; yyl < yyleng; ++yyl )
if ( yytext[yyl] == '\n' )
-
+
do{ yylineno++;
yycolumn=0;
}while(0)
;
}
+
do_action: /* This label is used only to access EOF actions. */
+
switch ( yy_act )
{ /* beginning of action switch */
case 0: /* must back up */
@@ -1654,74 +1891,77 @@
YY_BREAK
case 61:
YY_RULE_SETUP
-{ context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
+{ context->lexAfterType = true; return SAMPLER2DRECT; }
YY_BREAK
case 62:
YY_RULE_SETUP
-{ context->lexAfterType = true; return SAMPLER3D; }
+{ context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; }
YY_BREAK
case 63:
YY_RULE_SETUP
-{ return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); }
+{ context->lexAfterType = true; return SAMPLER3D; }
YY_BREAK
case 64:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, SAMPLER2DARRAY); }
+{ return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); }
YY_BREAK
case 65:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, ISAMPLER2D); }
+{ return ES2_identifier_ES3_keyword(context, SAMPLER2DARRAY); }
YY_BREAK
case 66:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, ISAMPLER3D); }
+{ return ES2_identifier_ES3_keyword(context, ISAMPLER2D); }
YY_BREAK
case 67:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, ISAMPLERCUBE); }
+{ return ES2_identifier_ES3_keyword(context, ISAMPLER3D); }
YY_BREAK
case 68:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, ISAMPLER2DARRAY); }
+{ return ES2_identifier_ES3_keyword(context, ISAMPLERCUBE); }
YY_BREAK
case 69:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, USAMPLER2D); }
+{ return ES2_identifier_ES3_keyword(context, ISAMPLER2DARRAY); }
YY_BREAK
case 70:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, USAMPLER3D); }
+{ return ES2_identifier_ES3_keyword(context, USAMPLER2D); }
YY_BREAK
case 71:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, USAMPLERCUBE); }
+{ return ES2_identifier_ES3_keyword(context, USAMPLER3D); }
YY_BREAK
case 72:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, USAMPLER2DARRAY); }
+{ return ES2_identifier_ES3_keyword(context, USAMPLERCUBE); }
YY_BREAK
case 73:
YY_RULE_SETUP
-{ return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); }
+{ return ES2_identifier_ES3_keyword(context, USAMPLER2DARRAY); }
YY_BREAK
case 74:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, SAMPLERCUBESHADOW); }
+{ return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); }
YY_BREAK
case 75:
YY_RULE_SETUP
-{ return ES2_identifier_ES3_keyword(context, SAMPLER2DARRAYSHADOW); }
+{ return ES2_identifier_ES3_keyword(context, SAMPLERCUBESHADOW); }
YY_BREAK
case 76:
YY_RULE_SETUP
-{ context->lexAfterType = true; return(STRUCT); }
+{ return ES2_identifier_ES3_keyword(context, SAMPLER2DARRAYSHADOW); }
YY_BREAK
case 77:
YY_RULE_SETUP
+{ context->lexAfterType = true; return(STRUCT); }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
{ return ES2_identifier_ES3_keyword(context, LAYOUT); }
YY_BREAK
/* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
-case 78:
case 79:
case 80:
case 81:
@@ -1777,6 +2017,7 @@
case 131:
case 132:
case 133:
+case 134:
YY_RULE_SETUP
{
if (context->getShaderVersion() < 300) {
@@ -1787,7 +2028,7 @@
}
YY_BREAK
/* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
-case 134:
+case 135:
YY_RULE_SETUP
{
if (context->getShaderVersion() >= 300)
@@ -1800,7 +2041,6 @@
}
YY_BREAK
/* Reserved keywords */
-case 135:
case 136:
case 137:
case 138:
@@ -2186,7 +2426,7 @@
{
yyg->yy_did_buffer_switch_on_eof = 0;
- if ( yywrap(yyscanner ) )
+ if ( yywrap( yyscanner ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
@@ -2242,6 +2482,10 @@
} /* end of user's declarations */
} /* end of yylex */
+
+
+
+
/* yy_get_next_buffer - try to read in a new buffer
*
* Returns a code representing an action:
@@ -2254,7 +2498,7 @@
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = yyg->yytext_ptr;
- yy_size_t number_to_move, i;
+ int number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -2283,7 +2527,7 @@
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -2296,7 +2540,7 @@
else
{
- yy_size_t num_to_read =
+ int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -2310,7 +2554,7 @@
if ( b->yy_is_our_buffer )
{
- yy_size_t new_size = b->yy_buf_size * 2;
+ int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@@ -2319,11 +2563,12 @@
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
+ b->yy_ch_buf = NULL;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
@@ -2351,7 +2596,7 @@
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- yyrestart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
}
else
@@ -2365,12 +2610,15 @@
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
}
yyg->yy_n_chars += number_to_move;
@@ -2382,6 +2630,7 @@
return ret_val;
}
+
/* yy_get_previous_state - get the state just before the EOB char was reached */
static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
@@ -2404,14 +2653,15 @@
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 821 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
}
return yy_current_state;
}
+
/* yy_try_NUL_trans - try to make a transition on the NUL character
*
* synopsis
@@ -2433,15 +2683,16 @@
{
yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 821 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
yy_is_jam = (yy_current_state == 820);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state;
}
+
#ifndef YY_NO_UNPUT
#endif
@@ -2471,7 +2722,7 @@
else
{ /* need more input */
- yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -2488,14 +2739,14 @@
*/
/* Reset buffer status. */
- yyrestart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
/*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( yywrap(yyscanner ) )
- return EOF;
+ if ( yywrap( yyscanner ) )
+ return 0;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
@@ -2518,7 +2769,7 @@
yyg->yy_hold_char = *++yyg->yy_c_buf_p;
if ( c == '\n' )
-
+
do{ yylineno++;
yycolumn=0;
}while(0)
@@ -2540,13 +2791,14 @@
if ( ! YY_CURRENT_BUFFER ){
yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- yy_load_buffer_state(yyscanner );
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
+ yy_load_buffer_state( yyscanner );
}
+
/** Switch to a different input buffer.
* @param new_buffer The new input buffer.
* @param yyscanner The scanner object.
@@ -2573,7 +2825,7 @@
}
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
/* We don't actually know whether we did this switch during
* EOF (yywrap()) processing, but the only time this flag
@@ -2583,6 +2835,7 @@
yyg->yy_did_buffer_switch_on_eof = 1;
}
+
static void yy_load_buffer_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -2602,26 +2855,27 @@
{
YY_BUFFER_STATE b;
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
- b->yy_buf_size = (yy_size_t)size;
+ b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- yy_init_buffer(b,file ,yyscanner);
+ yy_init_buffer( b, file , yyscanner);
return b;
}
+
/** Destroy the buffer.
* @param b a buffer created with yy_create_buffer()
* @param yyscanner The scanner object.
@@ -2637,11 +2891,12 @@
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- yyfree((void *) b->yy_ch_buf ,yyscanner );
+ yyfree( (void *) b->yy_ch_buf , yyscanner );
- yyfree((void *) b ,yyscanner );
+ yyfree( (void *) b , yyscanner );
}
+
/* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer,
* such as during a yyrestart() or at EOF.
@@ -2652,7 +2907,7 @@
int oerrno = errno;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flush_buffer(b ,yyscanner);
+ yy_flush_buffer( b , yyscanner);
b->yy_input_file = file;
b->yy_fill_buffer = 1;
@@ -2666,8 +2921,11 @@
b->yy_bs_column = 0;
}
+
+
b->yy_is_interactive = 0;
+
errno = oerrno;
}
@@ -2696,7 +2954,7 @@
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == YY_CURRENT_BUFFER )
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
/** Pushes the new state onto the stack. The new state becomes
@@ -2728,10 +2986,11 @@
YY_CURRENT_BUFFER_LVALUE = new_buffer;
/* copied from yy_switch_to_buffer. */
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
+
/** Removes and deletes the top of the stack, if present.
* The next element becomes the new top.
* @param yyscanner The scanner object.
@@ -2742,17 +3001,18 @@
if (!YY_CURRENT_BUFFER)
return;
- yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
YY_CURRENT_BUFFER_LVALUE = NULL;
if (yyg->yy_buffer_stack_top > 0)
--yyg->yy_buffer_stack_top;
if (YY_CURRENT_BUFFER) {
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
}
+
/* Allocates the stack if it does not exist.
* Guarantees space for at least one push.
*/
@@ -2767,15 +3027,16 @@
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1; // After all that talk, this was set to 1 anyways...
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
+
+
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
yyg->yy_buffer_stack_max = num_to_alloc;
yyg->yy_buffer_stack_top = 0;
return;
@@ -2800,11 +3061,15 @@
}
}
+
+
+
+
/** Setup the input buffer state to scan directly from a user-specified character buffer.
* @param base the character buffer
* @param size the size in bytes of the character buffer
* @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
@@ -2814,27 +3079,30 @@
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
- return 0;
+ return NULL;
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
+ b->yy_input_file = NULL;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- yy_switch_to_buffer(b ,yyscanner );
+ yy_switch_to_buffer( b , yyscanner );
return b;
}
+
+
+
/** Setup the input buffer state to scan a string. The next call to yylex() will
* scan from a @e copy of @a str.
* @param yystr a NUL-terminated string to scan
@@ -2843,12 +3111,15 @@
* @note If you want to scan bytes that may contain NUL values, then use
* yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
{
- return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
}
+
+
+
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
* scan from a @e copy of @a bytes.
* @param yybytes the byte buffer to scan
@@ -2856,16 +3127,16 @@
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) yyalloc(n ,yyscanner );
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n , yyscanner );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
@@ -2874,7 +3145,7 @@
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = yy_scan_buffer(buf,n ,yyscanner);
+ b = yy_scan_buffer( buf, n , yyscanner);
if ( ! b )
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
@@ -2886,15 +3157,25 @@
return b;
}
+
+
+
+
+
+
+
+
+
+
#ifndef YY_EXIT_FAILURE
#define YY_EXIT_FAILURE 2
#endif
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- (void) fprintf( stderr, "%s\n", msg );
+ fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
@@ -2915,8 +3196,11 @@
} \
while ( 0 )
+
+
/* Accessor methods (get/set functions) to struct members. */
+
/** Get the user-defined data for this scanner.
* @param yyscanner The scanner object.
*/
@@ -2926,12 +3210,15 @@
return yyextra;
}
+
+
/** Get the current line number.
* @param yyscanner The scanner object.
*/
int yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2939,12 +3226,16 @@
return yylineno;
}
+
+
+
/** Get the current column number.
* @param yyscanner The scanner object.
*/
int yyget_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2952,6 +3243,9 @@
return yycolumn;
}
+
+
+
/** Get the input stream.
* @param yyscanner The scanner object.
*/
@@ -2961,6 +3255,8 @@
return yyin;
}
+
+
/** Get the output stream.
* @param yyscanner The scanner object.
*/
@@ -2970,15 +3266,18 @@
return yyout;
}
+
+
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-yy_size_t yyget_leng (yyscan_t yyscanner)
+int yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
}
+
/** Get the current token.
* @param yyscanner The scanner object.
*/
@@ -2989,6 +3288,8 @@
return yytext;
}
+
+
/** Set the user-defined data. This data is never touched by the scanner.
* @param user_defined The data to be associated with this scanner.
* @param yyscanner The scanner object.
@@ -2999,6 +3300,8 @@
yyextra = user_defined ;
}
+
+
/** Set the current line number.
* @param _line_number line number
* @param yyscanner The scanner object.
@@ -3007,6 +3310,7 @@
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
YY_FATAL_ERROR( "yyset_lineno called with no buffer" );
@@ -3014,6 +3318,9 @@
yylineno = _line_number;
}
+
+
+
/** Set the current column.
* @param _column_no column number
* @param yyscanner The scanner object.
@@ -3022,6 +3329,7 @@
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
/* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
YY_FATAL_ERROR( "yyset_column called with no buffer" );
@@ -3029,6 +3337,10 @@
yycolumn = _column_no;
}
+
+
+
+
/** Set the input stream. This does not discard the current
* input buffer.
* @param _in_str A readable stream.
@@ -3041,59 +3353,77 @@
yyin = _in_str ;
}
+
+
void yyset_out (FILE * _out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyout = _out_str ;
}
+
+
+
int yyget_debug (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yy_flex_debug;
}
+
+
void yyset_debug (int _bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_flex_debug = _bdebug ;
}
+
/* Accessor methods for yylval and yylloc */
+
YYSTYPE * yyget_lval (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yylval;
}
+
+
void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylval = yylval_param;
}
+
+
+
YYLTYPE *yyget_lloc (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yylloc;
}
+
+
void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylloc = yylloc_param;
}
+
+
+
+
/* User-visible API */
/* yylex_init is special because it creates the scanner itself, so it is
* the ONLY reentrant function that doesn't take the scanner as the last argument.
* That's why we explicitly handle the declaration, instead of using our macros.
*/
-
int yylex_init(yyscan_t* ptr_yy_globals)
-
{
if (ptr_yy_globals == NULL){
errno = EINVAL;
@@ -3113,6 +3443,7 @@
return yy_init_globals ( *ptr_yy_globals );
}
+
/* yylex_init_extra has the same functionality as yylex_init, but follows the
* convention of taking the scanner as the last argument. Note however, that
* this is a *pointer* to a scanner, as it will be allocated by this call (and
@@ -3120,9 +3451,7 @@
* The user defined value in the first argument will be available to yyalloc in
* the yyextra field.
*/
-
-int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
{
struct yyguts_t dummy_yyguts;
@@ -3132,23 +3461,24 @@
errno = EINVAL;
return 1;
}
-
+
*ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return 1;
}
-
+
/* By setting to 0xAA, we expose bugs in
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
+
yyset_extra (yy_user_defined, *ptr_yy_globals);
-
+
return yy_init_globals ( *ptr_yy_globals );
}
+
static int yy_init_globals (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -3156,24 +3486,33 @@
* This function is called from yylex_destroy(), so don't allocate here.
*/
- yyg->yy_buffer_stack = 0;
+
+
+
+ yyg->yy_buffer_stack = NULL;
yyg->yy_buffer_stack_top = 0;
yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_c_buf_p = NULL;
yyg->yy_init = 0;
yyg->yy_start = 0;
+
yyg->yy_start_stack_ptr = 0;
yyg->yy_start_stack_depth = 0;
yyg->yy_start_stack = NULL;
+
+
+
+
+
/* Defined in main.c */
#ifdef YY_STDINIT
yyin = stdin;
yyout = stdout;
#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
+ yyin = NULL;
+ yyout = NULL;
#endif
/* For future reference: Set errno on error, since we are called by
@@ -3182,6 +3521,7 @@
return 0;
}
+
/* yylex_destroy is for both reentrant and non-reentrant scanners. */
int yylex_destroy (yyscan_t yyscanner)
{
@@ -3189,19 +3529,23 @@
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
- yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
YY_CURRENT_BUFFER_LVALUE = NULL;
yypop_buffer_state(yyscanner);
}
/* Destroy the stack itself. */
- yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyfree(yyg->yy_buffer_stack , yyscanner);
yyg->yy_buffer_stack = NULL;
+
/* Destroy the start condition stack. */
- yyfree(yyg->yy_start_stack ,yyscanner );
+ yyfree( yyg->yy_start_stack , yyscanner );
yyg->yy_start_stack = NULL;
+
+
+
/* Reset the globals. This is important in a non-reentrant scanner so the next time
* yylex() is called, initialization will occur. */
yy_init_globals( yyscanner);
@@ -3212,12 +3556,16 @@
return 0;
}
+
+
/*
* Internal utility routines.
*/
+
+
#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -3228,8 +3576,10 @@
}
#endif
+
+
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
{
int n;
for ( n = 0; s[n]; ++n )
@@ -3239,13 +3589,17 @@
}
#endif
+
+
void *yyalloc (yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- return (void *) malloc( size );
+ return malloc(size);
}
+
+
void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -3258,9 +3612,11 @@
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
- return (void *) realloc( (char *) ptr, size );
+ return realloc(ptr, size);
}
+
+
void yyfree (void * ptr , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -3268,16 +3624,24 @@
free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
}
+
#define YYTABLES_NAME "yytables"
+
+
+
+
+
+
+
yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
pp::Token token;
yyget_extra(yyscanner)->getPreprocessor().lex(&token);
yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
if (len < max_size)
memcpy(buf, token.text.c_str(), len);
- yyset_column(token.location.file,yyscanner);
- yyset_lineno(token.location.line,yyscanner);
+ yyset_column(token.location.file, yyscanner);
+ yyset_lineno(token.location.line, yyscanner);
if (len >= max_size)
YY_FATAL_ERROR("Input buffer overflow");
@@ -3360,7 +3724,7 @@
return 0;
}
- if (!atoi_clamp(yytext, &(yylval->lex.i)))
+ if (!atou_clamp(yytext, &(yylval->lex.u)))
yyextra->warning(*yylloc, "Integer overflow", yytext, "");
return UINTCONSTANT;
@@ -3412,7 +3776,7 @@
int glslang_initialize(TParseContext* context) {
yyscan_t scanner = NULL;
- if (yylex_init_extra(context,&scanner))
+ if (yylex_init_extra(context, &scanner))
return 1;
context->setScanner(scanner);
@@ -3431,9 +3795,9 @@
int glslang_scan(size_t count, const char* const string[], const int length[],
TParseContext* context) {
- yyrestart(NULL,context->getScanner());
- yyset_column(0,context->getScanner());
- yyset_lineno(1,context->getScanner());
+ yyrestart(NULL, context->getScanner());
+ yyset_column(0, context->getScanner());
+ yyset_lineno(1, context->getScanner());
context->AfterEOF = false;
// Initialize preprocessor.
@@ -3453,3 +3817,4 @@
return 0;
}
+
diff --git a/src/OpenGL/compiler/glslang_tab.cpp b/src/OpenGL/compiler/glslang_tab.cpp
index ea821d3..811da14 100644
--- a/src/OpenGL/compiler/glslang_tab.cpp
+++ b/src/OpenGL/compiler/glslang_tab.cpp
@@ -634,18 +634,18 @@
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 112
+#define YYFINAL 113
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 2525
+#define YYLAST 2530
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 128
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 93
/* YYNRULES -- Number of rules. */
-#define YYNRULES 272
+#define YYNRULES 273
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 413
+#define YYNSTATES 414
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
@@ -704,34 +704,34 @@
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 229, 229, 248, 251, 256, 261, 266, 271, 277,
- 280, 283, 286, 289, 292, 298, 306, 317, 321, 329,
- 332, 338, 342, 349, 355, 364, 372, 378, 385, 395,
- 398, 401, 404, 414, 415, 416, 417, 425, 426, 430,
- 434, 442, 443, 446, 452, 453, 457, 464, 465, 468,
- 471, 474, 480, 481, 484, 490, 491, 498, 499, 506,
- 507, 514, 515, 521, 522, 528, 529, 535, 536, 542,
- 543, 551, 552, 553, 554, 556, 557, 558, 561, 564,
- 567, 570, 576, 579, 590, 598, 606, 609, 615, 622,
- 626, 630, 634, 641, 647, 650, 657, 665, 686, 712,
- 722, 750, 755, 765, 770, 780, 783, 786, 789, 795,
- 802, 805, 809, 813, 818, 823, 830, 834, 838, 842,
- 847, 852, 856, 863, 873, 879, 882, 888, 894, 901,
- 910, 919, 927, 930, 937, 941, 945, 950, 958, 961,
- 965, 969, 978, 987, 995, 1005, 1017, 1020, 1023, 1029,
- 1036, 1039, 1045, 1048, 1051, 1057, 1060, 1065, 1080, 1084,
- 1088, 1092, 1096, 1100, 1105, 1110, 1115, 1120, 1125, 1130,
- 1135, 1140, 1145, 1150, 1155, 1160, 1166, 1172, 1178, 1184,
- 1190, 1196, 1202, 1208, 1214, 1219, 1224, 1233, 1238, 1243,
- 1248, 1253, 1258, 1263, 1268, 1273, 1278, 1283, 1288, 1293,
- 1298, 1303, 1316, 1316, 1319, 1319, 1325, 1328, 1344, 1347,
- 1356, 1360, 1366, 1373, 1388, 1392, 1396, 1397, 1403, 1404,
- 1405, 1406, 1407, 1408, 1409, 1413, 1414, 1414, 1414, 1424,
- 1425, 1429, 1429, 1430, 1430, 1435, 1438, 1448, 1451, 1457,
- 1458, 1462, 1470, 1474, 1481, 1481, 1488, 1491, 1498, 1503,
- 1518, 1518, 1523, 1523, 1530, 1530, 1538, 1541, 1547, 1550,
- 1556, 1560, 1567, 1570, 1573, 1576, 1579, 1588, 1592, 1599,
- 1602, 1608, 1608
+ 0, 229, 229, 249, 252, 257, 262, 267, 272, 278,
+ 281, 284, 287, 290, 293, 299, 307, 318, 322, 330,
+ 333, 339, 343, 350, 356, 365, 373, 379, 386, 396,
+ 399, 402, 405, 415, 416, 417, 418, 426, 427, 431,
+ 435, 443, 444, 447, 453, 454, 458, 465, 466, 469,
+ 472, 475, 481, 482, 485, 491, 492, 499, 500, 507,
+ 508, 515, 516, 522, 523, 529, 530, 536, 537, 543,
+ 544, 552, 553, 554, 555, 557, 558, 559, 562, 565,
+ 568, 571, 577, 580, 591, 599, 607, 610, 616, 623,
+ 627, 631, 635, 642, 648, 651, 658, 666, 687, 713,
+ 723, 751, 756, 766, 771, 781, 784, 787, 790, 796,
+ 803, 806, 810, 814, 819, 824, 831, 835, 839, 843,
+ 848, 853, 857, 864, 874, 880, 883, 889, 895, 902,
+ 911, 920, 928, 931, 938, 942, 946, 951, 959, 962,
+ 966, 970, 979, 988, 996, 1006, 1018, 1021, 1024, 1030,
+ 1037, 1040, 1046, 1049, 1052, 1058, 1061, 1066, 1081, 1085,
+ 1089, 1093, 1097, 1101, 1106, 1111, 1116, 1121, 1126, 1131,
+ 1136, 1141, 1146, 1151, 1156, 1161, 1167, 1173, 1179, 1185,
+ 1191, 1197, 1203, 1209, 1215, 1220, 1225, 1234, 1243, 1248,
+ 1253, 1258, 1263, 1268, 1273, 1278, 1283, 1288, 1293, 1298,
+ 1303, 1308, 1313, 1326, 1326, 1329, 1329, 1335, 1338, 1354,
+ 1357, 1366, 1370, 1376, 1383, 1398, 1402, 1406, 1407, 1413,
+ 1414, 1415, 1416, 1417, 1418, 1419, 1423, 1424, 1424, 1424,
+ 1434, 1435, 1439, 1439, 1440, 1440, 1445, 1448, 1458, 1461,
+ 1467, 1468, 1472, 1480, 1484, 1491, 1491, 1498, 1501, 1508,
+ 1513, 1528, 1528, 1533, 1533, 1540, 1540, 1548, 1551, 1557,
+ 1560, 1566, 1570, 1577, 1580, 1583, 1586, 1589, 1598, 1602,
+ 1609, 1612, 1618, 1618
};
#endif
@@ -820,12 +820,12 @@
};
# endif
-#define YYPACT_NINF -334
+#define YYPACT_NINF -344
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-334)))
+ (!!((Yystate) == (-344)))
-#define YYTABLE_NINF -232
+#define YYTABLE_NINF -233
#define yytable_value_is_error(Yytable_value) \
0
@@ -834,48 +834,48 @@
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- 2163, 10, -334, -334, -334, 169, -334, -334, -334, -334,
- -334, -334, -334, -334, -334, -334, -334, -334, -334, -334,
- -334, -334, -334, -334, -334, -334, -334, -334, -334, -334,
- -334, -334, -334, -334, -334, -334, -334, 69, -334, -334,
- -48, -334, -334, -334, -334, -334, -334, -334, -334, -334,
- -334, -334, -334, -334, -334, -334, -334, -334, -82, -334,
- -334, -78, -73, -71, 1, -59, -334, -32, 113, 1182,
- -334, -334, 2448, 113, -334, -23, -334, 2088, -334, -334,
- -334, -334, 113, -334, 2448, -334, -334, 11, -334, 9,
- -334, 20, -334, 121, -334, -334, -334, -334, -334, 2312,
- 150, 22, -334, -79, -334, 37, -334, 2238, -334, -334,
- -334, 1252, -334, -334, -334, 62, -334, 2238, 44, -41,
- -334, 410, -334, -334, -334, -334, 105, 2312, -76, -334,
- 1350, 1641, -334, 107, 2312, 117, 1833, -334, 91, -334,
- -334, -334, -334, -334, 1641, 1641, 1641, -334, -334, -334,
- -334, -334, -334, -334, 19, -334, -334, -334, 103, -24,
- 1736, 120, -334, 1641, 80, -42, -36, 15, 43, 99,
- 108, 104, 141, 142, -69, -334, 127, -334, -334, 2238,
- 1918, 87, -334, 9, 122, 124, -334, 135, 136, 129,
- 1448, 140, 1641, 133, 143, 137, -334, -334, 118, -334,
- -334, 12, -334, -78, 145, -334, -334, -334, -334, 526,
- -334, -334, -334, -334, -334, -334, 144, -334, -334, 1543,
- 1641, 138, 148, -334, -334, 117, 146, 28, -334, -58,
- -334, -334, -334, -15, -334, -334, 1641, 2380, -334, -334,
- 1641, 154, -334, -334, -334, 1641, 1641, 1641, 1641, 1641,
- 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
- 1641, 1641, 1641, 1641, 1641, -334, 2003, -334, -334, -334,
- -334, -334, -334, 152, -334, 1641, -334, -334, 41, 1641,
- 149, -334, -334, -334, 642, -334, -334, -334, -334, -334,
- -334, -334, -334, -334, -334, -334, 1641, 1641, -334, -334,
- -334, 1641, 151, 155, -334, 1641, 157, 57, 1641, 117,
- -334, -85, -334, -334, 156, 160, -334, 161, -334, -334,
- -334, -334, -334, 80, 80, -42, -42, -36, -36, -36,
- -36, 15, 15, 43, 99, 108, 104, 141, 142, 72,
- -334, 211, 20, 874, 990, -10, -334, 3, -334, 1087,
- 642, -334, -334, 165, 1641, 163, -334, 1641, -334, 166,
- -334, 1641, -334, -334, 1641, 164, -334, -334, -334, -334,
- 1087, 152, -334, 160, 198, 2312, 172, 170, -334, -334,
- 1641, -334, -334, 171, -334, 1641, -334, 167, 175, 265,
- -334, 178, 174, 758, -334, -334, 176, 13, 1641, 758,
- 152, -334, 1641, -334, -334, -334, -334, 177, 160, -334,
- -334, -334, -334
+ 2168, 120, -344, -344, -344, 146, -344, -344, -344, -344,
+ -344, -344, -344, -344, -344, -344, -344, -344, -344, -344,
+ -344, -344, -344, -344, -344, -344, -344, -344, -344, -344,
+ -344, -344, -344, -344, -344, -344, -344, 127, -344, -344,
+ -41, -344, -344, -344, -344, -344, -344, -344, -344, -344,
+ -344, -344, -344, -344, -344, -344, -344, -344, -344, -84,
+ -344, -344, -68, -57, -39, 1, -89, -344, 41, 14,
+ 1187, -344, -344, 2453, 14, -344, 15, -344, 2093, -344,
+ -344, -344, -344, 14, -344, 2453, -344, -344, 18, -344,
+ 47, -344, 26, -344, 10, -344, -344, -344, -344, -344,
+ 2317, 113, 60, -344, -66, -344, 31, -344, 2243, -344,
+ -344, -344, 1257, -344, -344, -344, -45, -344, 2243, 46,
+ -21, -344, 415, -344, -344, -344, -344, 68, 2317, -42,
+ -344, 1355, 1646, -344, 188, 2317, 89, 1838, -344, 85,
+ -344, -344, -344, -344, -344, 1646, 1646, 1646, -344, -344,
+ -344, -344, -344, -344, -344, 39, -344, -344, -344, 74,
+ -17, 1741, 96, -344, 1646, 37, -37, 91, -61, 87,
+ 65, 81, 71, 116, 115, -64, -344, 102, -344, -344,
+ 2243, 1923, 105, -344, 47, 97, 99, -344, 110, 131,
+ 124, 1453, 138, 1646, 132, 142, 140, -344, -344, 123,
+ -344, -344, -77, -344, -68, 143, -344, -344, -344, -344,
+ 531, -344, -344, -344, -344, -344, -344, 144, -344, -344,
+ 1548, 1646, 141, 148, -344, -344, 89, 145, -9, -344,
+ -58, -344, -344, -344, -13, -344, -344, 1646, 2385, -344,
+ -344, 1646, 152, -344, -344, -344, 1646, 1646, 1646, 1646,
+ 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646, 1646,
+ 1646, 1646, 1646, 1646, 1646, 1646, -344, 2008, -344, -344,
+ -344, -344, -344, -344, 150, -344, 1646, -344, -344, -7,
+ 1646, 147, -344, -344, -344, 647, -344, -344, -344, -344,
+ -344, -344, -344, -344, -344, -344, -344, 1646, 1646, -344,
+ -344, -344, 1646, 149, 153, -344, 1646, 151, 5, 1646,
+ 89, -344, -70, -344, -344, 158, 157, -344, 165, -344,
+ -344, -344, -344, -344, 37, 37, -37, -37, 91, 91,
+ 91, 91, -61, -61, 87, 65, 81, 71, 116, 115,
+ 75, -344, 214, 26, 879, 995, -8, -344, 4, -344,
+ 1092, 647, -344, -344, 164, 1646, 159, -344, 1646, -344,
+ 166, -344, 1646, -344, -344, 1646, 170, -344, -344, -344,
+ -344, 1092, 150, -344, 157, 200, 2317, 172, 169, -344,
+ -344, 1646, -344, -344, 173, -344, 1646, -344, 167, 174,
+ 265, -344, 175, 171, 763, -344, -344, 177, 9, 1646,
+ 763, 150, -344, 1646, -344, -344, -344, -344, 178, 157,
+ -344, -344, -344, -344
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -887,74 +887,74 @@
160, 161, 166, 167, 168, 169, 170, 171, 163, 164,
165, 172, 173, 174, 175, 176, 177, 139, 140, 143,
129, 178, 179, 180, 181, 182, 183, 0, 126, 125,
- 0, 158, 184, 185, 186, 188, 189, 190, 191, 192,
- 193, 194, 195, 196, 187, 197, 198, 199, 0, 201,
- 270, 271, 0, 95, 105, 0, 110, 116, 133, 0,
- 131, 123, 0, 134, 144, 155, 200, 0, 267, 269,
- 130, 122, 0, 136, 0, 141, 142, 0, 204, 0,
- 86, 0, 93, 105, 127, 106, 107, 108, 96, 0,
- 105, 0, 87, 117, 132, 0, 92, 0, 124, 145,
- 135, 0, 1, 268, 137, 0, 202, 0, 152, 0,
- 150, 0, 272, 97, 102, 104, 109, 0, 111, 98,
- 0, 0, 85, 0, 0, 0, 0, 206, 2, 6,
- 4, 5, 7, 28, 0, 0, 0, 156, 35, 34,
- 36, 33, 3, 9, 29, 11, 16, 17, 0, 0,
- 22, 0, 37, 0, 41, 44, 47, 52, 55, 57,
- 59, 61, 63, 65, 67, 84, 0, 26, 88, 0,
- 0, 0, 149, 0, 0, 0, 252, 0, 0, 0,
- 0, 0, 0, 0, 0, 226, 235, 239, 37, 69,
- 82, 0, 215, 0, 144, 218, 237, 217, 216, 0,
- 219, 220, 221, 222, 223, 224, 99, 101, 103, 0,
- 0, 0, 0, 214, 121, 0, 212, 0, 210, 0,
- 207, 30, 31, 0, 13, 14, 0, 0, 20, 19,
- 0, 158, 23, 25, 32, 0, 0, 0, 0, 0,
+ 0, 158, 184, 185, 186, 187, 189, 190, 191, 192,
+ 193, 194, 195, 196, 197, 188, 198, 199, 200, 0,
+ 202, 271, 272, 0, 95, 105, 0, 110, 116, 133,
+ 0, 131, 123, 0, 134, 144, 155, 201, 0, 268,
+ 270, 130, 122, 0, 136, 0, 141, 142, 0, 205,
+ 0, 86, 0, 93, 105, 127, 106, 107, 108, 96,
+ 0, 105, 0, 87, 117, 132, 0, 92, 0, 124,
+ 145, 135, 0, 1, 269, 137, 0, 203, 0, 152,
+ 0, 150, 0, 273, 97, 102, 104, 109, 0, 111,
+ 98, 0, 0, 85, 0, 0, 0, 0, 207, 2,
+ 6, 4, 5, 7, 28, 0, 0, 0, 156, 35,
+ 34, 36, 33, 3, 9, 29, 11, 16, 17, 0,
+ 0, 22, 0, 37, 0, 41, 44, 47, 52, 55,
+ 57, 59, 61, 63, 65, 67, 84, 0, 26, 88,
+ 0, 0, 0, 149, 0, 0, 0, 253, 0, 0,
+ 0, 0, 0, 0, 0, 0, 227, 236, 240, 37,
+ 69, 82, 0, 216, 0, 144, 219, 238, 218, 217,
+ 0, 220, 221, 222, 223, 224, 225, 99, 101, 103,
+ 0, 0, 0, 0, 215, 121, 0, 213, 0, 211,
+ 0, 208, 30, 31, 0, 13, 14, 0, 0, 20,
+ 19, 0, 158, 23, 25, 32, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 157, 0, 205, 153, 154,
- 151, 263, 262, 233, 254, 0, 266, 264, 0, 0,
- 0, 247, 250, 225, 0, 72, 73, 75, 74, 77,
- 78, 79, 80, 81, 76, 71, 0, 0, 240, 236,
- 238, 0, 0, 0, 115, 0, 118, 0, 0, 0,
- 208, 0, 89, 8, 0, 15, 27, 12, 18, 24,
- 38, 39, 40, 43, 42, 45, 46, 50, 51, 48,
- 49, 53, 54, 56, 58, 60, 62, 64, 66, 0,
- 203, 0, 0, 0, 0, 0, 265, 0, 246, 0,
- 227, 70, 83, 0, 0, 112, 119, 0, 209, 0,
- 211, 0, 90, 10, 0, 0, 232, 234, 257, 256,
- 259, 233, 244, 248, 0, 0, 0, 0, 100, 113,
- 0, 120, 213, 0, 68, 0, 258, 0, 0, 243,
- 241, 0, 0, 0, 228, 114, 0, 0, 260, 0,
- 233, 245, 0, 230, 251, 229, 91, 0, 261, 255,
- 242, 249, 253
+ 0, 0, 0, 0, 0, 0, 157, 0, 206, 153,
+ 154, 151, 264, 263, 234, 255, 0, 267, 265, 0,
+ 0, 0, 248, 251, 226, 0, 72, 73, 75, 74,
+ 77, 78, 79, 80, 81, 76, 71, 0, 0, 241,
+ 237, 239, 0, 0, 0, 115, 0, 118, 0, 0,
+ 0, 209, 0, 89, 8, 0, 15, 27, 12, 18,
+ 24, 38, 39, 40, 43, 42, 45, 46, 50, 51,
+ 48, 49, 53, 54, 56, 58, 60, 62, 64, 66,
+ 0, 204, 0, 0, 0, 0, 0, 266, 0, 247,
+ 0, 228, 70, 83, 0, 0, 112, 119, 0, 210,
+ 0, 212, 0, 90, 10, 0, 0, 233, 235, 258,
+ 257, 260, 234, 245, 249, 0, 0, 0, 0, 100,
+ 113, 0, 120, 214, 0, 68, 0, 259, 0, 0,
+ 244, 242, 0, 0, 0, 229, 114, 0, 0, 261,
+ 0, 234, 246, 0, 231, 252, 230, 91, 0, 262,
+ 256, 243, 250, 254
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int16 yypgoto[] =
{
- -334, -334, -334, -334, -334, -334, -334, 46, -334, -334,
- -334, -334, 66, -334, -46, -44, -67, -34, 30, 33,
- 29, 32, 34, 31, -334, -104, -127, -334, -144, -119,
- -334, 14, 17, -334, -334, -334, 168, 204, 199, 173,
- -334, -334, -325, 8, -334, -101, 7, -68, 293, -334,
- -334, 119, 0, -334, -334, -334, -334, -97, -123, 76,
- -6, -208, -40, -206, -328, -83, -334, -334, -94, -333,
- -334, -334, -86, 25, -38, -334, -334, -334, -334, -334,
- -60, -334, -334, -334, -334, -334, -334, -334, -334, -334,
- 253, -334, -334
+ -344, -344, -344, -344, -344, -344, -344, 48, -344, -344,
+ -344, -344, 70, -344, -56, -49, -123, -53, 28, 29,
+ 27, 32, 30, 33, -344, -110, -128, -344, -138, -119,
+ -344, 11, 17, -344, -344, -344, 168, 201, 197, 176,
+ -344, -344, -326, 7, -344, -105, 13, -69, 294, -344,
+ -344, 117, 0, -344, -344, -344, -344, -103, -121, 76,
+ -10, -215, -40, -203, -314, -86, -344, -344, -97, -343,
+ -344, -344, -87, 23, -36, -344, -344, -344, -344, -344,
+ -60, -344, -344, -344, -344, -344, -344, -344, -344, -344,
+ 232, -344, -344
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
- -1, 152, 153, 154, 314, 155, 156, 157, 158, 159,
- 160, 161, 198, 163, 164, 165, 166, 167, 168, 169,
- 170, 171, 172, 173, 174, 199, 200, 296, 201, 176,
- 107, 202, 203, 62, 63, 64, 124, 98, 99, 125,
- 65, 66, 67, 68, 100, 69, 70, 71, 72, 73,
- 119, 120, 177, 75, 76, 179, 117, 136, 137, 227,
- 228, 224, 205, 206, 207, 208, 284, 377, 404, 341,
- 342, 343, 405, 209, 210, 211, 390, 212, 391, 213,
- 376, 214, 349, 273, 344, 370, 387, 388, 215, 77,
- 78, 79, 91
+ -1, 153, 154, 155, 315, 156, 157, 158, 159, 160,
+ 161, 162, 199, 164, 165, 166, 167, 168, 169, 170,
+ 171, 172, 173, 174, 175, 200, 201, 297, 202, 177,
+ 108, 203, 204, 63, 64, 65, 125, 99, 100, 126,
+ 66, 67, 68, 69, 101, 70, 71, 72, 73, 74,
+ 120, 121, 178, 76, 77, 180, 118, 137, 138, 228,
+ 229, 225, 206, 207, 208, 209, 285, 378, 405, 342,
+ 343, 344, 406, 210, 211, 212, 391, 213, 392, 214,
+ 377, 215, 350, 274, 345, 371, 388, 389, 216, 78,
+ 79, 80, 92
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -962,461 +962,454 @@
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int16 yytable[] =
{
- 74, 108, 233, 300, 223, 122, 134, 175, 83, 82,
- 94, 222, 304, 230, 60, 367, 134, 61, 311, 7,
- 180, 361, 89, 263, 374, 129, 175, 130, 87, 362,
- 219, 126, 92, 242, 131, 134, 90, 220, 389, 135,
- 93, 95, 96, 97, 103, 374, 278, 250, 251, 135,
- 27, 28, 101, 29, 80, 102, 312, 230, 264, 126,
- 88, 37, 38, 39, 182, 403, 225, 410, 135, 74,
- 183, 403, 109, 280, 248, 104, 249, 74, 134, 134,
- 110, 239, 266, 111, 115, 118, 81, 240, 175, 114,
- 313, 60, 315, 223, 61, 371, 297, 356, 128, 74,
- 303, 297, 252, 253, 234, 235, -94, 74, 372, 85,
- 86, 135, 135, 319, 297, 175, 7, 74, 407, 116,
- 339, 204, 7, 297, 297, 236, 298, 74, 121, 237,
- 94, 345, 256, 257, 74, 347, 74, 254, 255, 309,
- 83, 82, 310, 230, 300, 132, 379, 27, 28, 381,
- 29, 80, 297, 27, 28, 346, 29, 181, 37, 38,
- 39, 95, 96, 97, 37, 134, 268, 269, 309, 351,
- 352, 358, 395, 2, 3, 4, 178, 162, 223, 74,
- 74, 216, 353, 297, 364, 327, 328, 329, 330, 359,
- 95, 96, 97, 226, 411, -27, 162, 175, 135, 245,
- 246, 247, 323, 324, 175, 373, 325, 326, 238, 204,
- 231, 232, 285, 286, 287, 288, 289, 290, 291, 292,
- 293, 294, 331, 332, 243, 258, 373, 223, 260, 244,
- 223, 295, 261, 259, 265, 262, 271, 384, 272, 274,
- 275, 397, 383, 276, 279, 281, 283, 282, 375, -26,
- 301, 305, 308, 223, 408, 306, 366, 175, 162, -21,
- -231, 348, 355, 363, 354, -28, 74, 365, 385, 375,
- 357, 297, 378, 382, 392, 223, 380, 393, 396, 394,
- 399, 398, 400, 318, 204, 162, 195, 402, 333, 335,
- 406, 412, 334, 336, 338, 217, 337, 123, 84, 127,
- 218, 307, 270, 360, 368, 409, 369, 108, 401, 350,
- 386, 320, 321, 322, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
- 113, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 204, 204, 0, 0, 0, 0, 204,
- 204, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 162, 0, 0,
- 204, 0, 0, 0, 162, 74, 0, 0, 0, 0,
+ 75, 109, 176, 135, 224, 123, 305, 301, 83, 234,
+ 95, 61, 223, 135, 84, 181, 231, 62, 312, 95,
+ 90, 176, 102, 7, 375, 103, 253, 254, 264, 390,
+ 368, 127, 135, 243, 298, 88, 362, 299, 130, 136,
+ 131, 96, 97, 98, 363, 375, 91, 132, 93, 136,
+ 96, 97, 98, 279, 27, 28, 313, 29, 411, 127,
+ 231, 255, 256, 265, 220, 37, 226, 89, 136, 179,
+ 75, 221, 94, 110, 281, 135, 135, 267, 75, 249,
+ 404, 250, 105, 176, 183, 116, 404, 111, 240, 61,
+ 184, 357, 314, 224, 241, 62, 115, 372, 298, 316,
+ 75, 304, 310, 298, 298, 311, -94, 347, 75, 373,
+ 176, 136, 136, 320, 408, 298, 310, 104, 75, 359,
+ 298, 112, 205, 119, 235, 236, 117, 340, 75, 7,
+ 328, 329, 330, 331, 122, 75, 129, 75, 346, 133,
+ 380, 83, 348, 382, 217, 237, 231, 84, 301, 238,
+ 2, 3, 4, 96, 97, 98, 246, 247, 248, 182,
+ 27, 28, 135, 29, 81, 227, 396, 86, 87, 352,
+ 353, 37, 38, 39, 251, 252, 257, 258, 224, 239,
+ 75, 75, 163, 354, 269, 270, 298, 365, 412, -27,
+ 360, 259, 176, 324, 325, 261, 82, 7, 136, 176,
+ 244, 163, 326, 327, 332, 333, 260, 262, 263, 266,
+ 205, 272, 374, 273, 275, 232, 233, 286, 287, 288,
+ 289, 290, 291, 292, 293, 294, 295, 224, 27, 28,
+ 224, 29, 81, 374, 245, 276, 296, 385, 277, 37,
+ 38, 39, 280, 384, 282, 376, 283, -26, 398, 284,
+ 302, 309, 176, 224, 306, 307, 367, -21, -232, 349,
+ 356, 409, 355, 163, 358, 364, 376, 75, 298, -28,
+ 366, 379, 381, 383, 386, 224, 393, 394, 395, 400,
+ 397, 399, 401, 196, 403, 205, 319, 334, 336, 335,
+ 163, 407, 413, 338, 337, 124, 218, 339, 128, 85,
+ 361, 271, 308, 410, 219, 369, 402, 109, 351, 370,
+ 114, 387, 0, 0, 0, 0, 321, 322, 323, 163,
+ 163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
+ 163, 163, 163, 163, 163, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 205, 205, 0, 0, 0, 0,
+ 205, 205, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 204, 0, 0, 0, 0, 0, 204,
+ 0, 205, 163, 0, 0, 0, 75, 0, 0, 163,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 184, 185, 186, 162, 187, 188,
- 189, 190, 191, 192, 193, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 0, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 194, 42, 43, 44,
- 0, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 0, 55, 56, 57, 58, 138, 59, 139, 140,
- 141, 142, 143, 0, 0, 144, 145, 0, 0, 0,
+ 0, 0, 0, 0, 205, 0, 0, 0, 0, 0,
+ 205, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 185,
+ 186, 187, 163, 188, 189, 190, 191, 192, 193, 194,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 0, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 195, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 0, 56, 57, 58,
+ 59, 139, 60, 140, 141, 142, 143, 144, 0, 0,
+ 145, 146, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 147,
+ 0, 0, 0, 196, 197, 0, 0, 0, 0, 198,
+ 149, 150, 151, 152, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 185, 186, 187, 0, 188,
+ 189, 190, 191, 192, 193, 194, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 0, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 195, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 0, 56, 57, 58, 59, 139, 60, 140,
+ 141, 142, 143, 144, 0, 0, 145, 146, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 146, 0, 0, 0, 195, 196,
- 0, 0, 0, 0, 197, 148, 149, 150, 151, 1,
- 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 184, 185, 186, 0, 187, 188, 189, 190, 191, 192,
- 193, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 0, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 194, 42, 43, 44, 0, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 0, 55, 56,
- 57, 58, 138, 59, 139, 140, 141, 142, 143, 0,
- 0, 144, 145, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 146, 0, 0, 0, 195, 299, 0, 0, 0, 0,
- 197, 148, 149, 150, 151, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 184, 185, 186, 0,
- 187, 188, 189, 190, 191, 192, 193, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 0, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, 194, 42,
- 43, 44, 0, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 0, 55, 56, 57, 58, 138, 59,
- 139, 140, 141, 142, 143, 0, 0, 144, 145, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 146, 0, 0, 0,
- 195, 0, 0, 0, 0, 0, 197, 148, 149, 150,
- 151, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 184, 185, 186, 0, 187, 188, 189, 190,
- 191, 192, 193, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 0, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 194, 42, 43, 44, 0, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 0,
- 55, 56, 57, 58, 138, 59, 139, 140, 141, 142,
- 143, 0, 0, 144, 145, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 146, 0, 0, 0, 121, 0, 0, 0,
- 0, 0, 197, 148, 149, 150, 151, 1, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 184, 185,
- 186, 0, 187, 188, 189, 190, 191, 192, 193, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 0, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
- 194, 42, 43, 44, 0, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 0, 55, 56, 57, 58,
- 138, 59, 139, 140, 141, 142, 143, 0, 0, 144,
- 145, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 146, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 197, 148,
- 149, 150, 151, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 0, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 0, 42, 43, 44,
- 0, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 0, 55, 56, 57, 58, 138, 59, 139, 140,
- 141, 142, 143, 0, 0, 144, 145, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 133, 2, 3, 4, 146, 6, 7, 8, 9, 10,
- 11, 0, 0, 0, 197, 148, 149, 150, 151, 0,
- 0, 0, 12, 13, 14, 15, 16, 17, 18, 19,
+ 0, 0, 0, 0, 0, 147, 0, 0, 0, 196,
+ 300, 0, 0, 0, 0, 198, 149, 150, 151, 152,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 185, 186, 187, 0, 188, 189, 190, 191, 192,
+ 193, 194, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 0,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 0, 42, 43, 44, 0, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 0, 55,
- 56, 57, 58, 138, 59, 139, 140, 141, 142, 143,
- 0, 0, 144, 145, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 2, 3, 4, 0,
- 0, 146, 8, 9, 10, 11, 0, 0, 0, 0,
- 0, 0, 148, 149, 150, 151, 0, 12, 13, 14,
+ 39, 40, 41, 195, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 0, 56,
+ 57, 58, 59, 139, 60, 140, 141, 142, 143, 144,
+ 0, 0, 145, 146, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 147, 0, 0, 0, 196, 0, 0, 0, 0,
+ 0, 198, 149, 150, 151, 152, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 185, 186, 187,
+ 0, 188, 189, 190, 191, 192, 193, 194, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 0, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 195,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 59, 139,
+ 60, 140, 141, 142, 143, 144, 0, 0, 145, 146,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 147, 0, 0,
+ 0, 122, 0, 0, 0, 0, 0, 198, 149, 150,
+ 151, 152, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 185, 186, 187, 0, 188, 189, 190,
+ 191, 192, 193, 194, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 0, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 195, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 0, 56, 57, 58, 59, 139, 60, 140, 141, 142,
+ 143, 144, 0, 0, 145, 146, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 147, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 198, 149, 150, 151, 152, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 0, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 0, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 0, 56, 57, 58,
+ 59, 139, 60, 140, 141, 142, 143, 144, 0, 0,
+ 145, 146, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 134, 2, 3, 4, 147,
+ 6, 7, 8, 9, 10, 11, 0, 0, 0, 198,
+ 149, 150, 151, 152, 0, 0, 0, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 0, 0, 0, 0, 0, 31, 32, 33,
- 34, 35, 36, 0, 0, 0, 40, 41, 0, 42,
- 43, 44, 0, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 0, 55, 56, 57, 0, 105, 59,
- 0, 0, 8, 9, 10, 11, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 0, 0, 0, 0, 106, 31, 32, 33,
- 34, 35, 36, 0, 0, 0, 40, 41, 0, 42,
- 43, 44, 0, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 0, 55, 56, 57, 0, 138, 59,
- 139, 140, 141, 142, 143, 0, 0, 144, 145, 0,
+ 25, 26, 27, 28, 0, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 0, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 0, 56, 57, 58, 59, 139, 60,
+ 140, 141, 142, 143, 144, 0, 0, 145, 146, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 146, 0, 0, 147,
- 8, 9, 10, 11, 0, 0, 0, 148, 149, 150,
- 151, 0, 0, 0, 0, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 0, 0, 0, 0, 0, 31, 32, 33, 34, 35,
- 36, 0, 0, 0, 40, 41, 0, 42, 43, 44,
- 0, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 0, 55, 56, 57, 0, 138, 59, 139, 140,
- 141, 142, 143, 0, 0, 144, 145, 0, 0, 0,
+ 0, 2, 3, 4, 0, 0, 147, 8, 9, 10,
+ 11, 0, 0, 0, 0, 0, 0, 149, 150, 151,
+ 152, 0, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 0, 0, 0,
+ 0, 0, 31, 32, 33, 34, 35, 36, 0, 0,
+ 0, 40, 41, 0, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 0, 56,
+ 57, 58, 0, 106, 60, 0, 0, 8, 9, 10,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 0, 0, 0,
+ 0, 107, 31, 32, 33, 34, 35, 36, 0, 0,
+ 0, 40, 41, 0, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 0, 56,
+ 57, 58, 0, 139, 60, 140, 141, 142, 143, 144,
+ 0, 0, 145, 146, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 146, 0, 0, 221, 8, 9,
- 10, 11, 0, 0, 0, 148, 149, 150, 151, 0,
- 0, 0, 0, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 0, 0,
- 0, 0, 0, 31, 32, 33, 34, 35, 36, 0,
- 0, 0, 40, 41, 0, 42, 43, 44, 0, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 0,
- 55, 56, 57, 0, 138, 59, 139, 140, 141, 142,
- 143, 0, 0, 144, 145, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 146, 8, 9, 10, 11, 0, 0, 0,
- 0, 0, 277, 148, 149, 150, 151, 0, 12, 13,
+ 0, 147, 0, 0, 148, 8, 9, 10, 11, 0,
+ 0, 0, 149, 150, 151, 152, 0, 0, 0, 0,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 0, 0, 0, 0, 0,
+ 31, 32, 33, 34, 35, 36, 0, 0, 0, 40,
+ 41, 0, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 0, 56, 57, 58,
+ 0, 139, 60, 140, 141, 142, 143, 144, 0, 0,
+ 145, 146, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 147,
+ 0, 0, 222, 8, 9, 10, 11, 0, 0, 0,
+ 149, 150, 151, 152, 0, 0, 0, 0, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 0, 0, 0, 0, 0, 31, 32,
33, 34, 35, 36, 0, 0, 0, 40, 41, 0,
- 42, 43, 44, 0, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 0, 55, 56, 57, 0, 138,
- 59, 139, 140, 141, 142, 143, 0, 0, 144, 145,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 0, 139,
+ 60, 140, 141, 142, 143, 144, 0, 0, 145, 146,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 146, 0, 0,
- 302, 8, 9, 10, 11, 0, 0, 0, 148, 149,
- 150, 151, 0, 0, 0, 0, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 0, 0, 0, 0, 0, 31, 32, 33, 34,
- 35, 36, 0, 0, 0, 40, 41, 0, 42, 43,
- 44, 0, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 0, 55, 56, 57, 0, 138, 59, 139,
- 140, 141, 142, 143, 0, 0, 144, 145, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 147, 8, 9,
+ 10, 11, 0, 0, 0, 0, 0, 278, 149, 150,
+ 151, 152, 0, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 0, 0,
+ 0, 0, 0, 31, 32, 33, 34, 35, 36, 0,
+ 0, 0, 40, 41, 0, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 0,
+ 56, 57, 58, 0, 139, 60, 140, 141, 142, 143,
+ 144, 0, 0, 145, 146, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 146, 8, 9, 10, 11,
- 0, 0, 0, 0, 0, 0, 148, 149, 150, 151,
+ 0, 0, 147, 0, 0, 303, 8, 9, 10, 11,
+ 0, 0, 0, 149, 150, 151, 152, 0, 0, 0,
0, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 0, 0, 0, 0,
0, 31, 32, 33, 34, 35, 36, 0, 0, 0,
- 40, 241, 0, 42, 43, 44, 0, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 0, 55, 56,
- 57, 0, 138, 59, 139, 140, 141, 142, 143, 0,
- 0, 144, 145, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 133, 2, 3, 4,
- 146, 6, 7, 8, 9, 10, 11, 0, 0, 0,
- 0, 148, 149, 150, 151, 0, 0, 0, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 0, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 0,
- 42, 43, 44, 0, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 0, 55, 56, 57, 58, 0,
- 59, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 133, 2, 3, 4, 0, 6, 7, 8, 9,
- 10, 11, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 229, 12, 13, 14, 15, 16, 17, 18,
+ 40, 41, 0, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 0, 56, 57,
+ 58, 0, 139, 60, 140, 141, 142, 143, 144, 0,
+ 0, 145, 146, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 147, 8, 9, 10, 11, 0, 0, 0, 0, 0,
+ 0, 149, 150, 151, 152, 0, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 0, 0, 0, 0, 0, 31, 32, 33, 34,
+ 35, 36, 0, 0, 0, 40, 242, 0, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 0, 56, 57, 58, 0, 139, 60, 140,
+ 141, 142, 143, 144, 0, 0, 145, 146, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 134, 2, 3, 4, 147, 6, 7, 8, 9,
+ 10, 11, 0, 0, 0, 0, 149, 150, 151, 152,
+ 0, 0, 0, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
0, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 0, 42, 43, 44, 0, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 0,
- 55, 56, 57, 58, 0, 59, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 133, 2, 3, 4,
+ 38, 39, 40, 41, 0, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 0,
+ 56, 57, 58, 59, 0, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 134, 2, 3, 4,
0, 6, 7, 8, 9, 10, 11, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 267, 12, 13,
+ 0, 0, 0, 0, 0, 0, 0, 230, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 0, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 0,
- 42, 43, 44, 0, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 0, 55, 56, 57, 58, 0,
- 59, 0, 0, 0, 0, 0, 0, 0, 112, 0,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 59, 0,
+ 60, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 134, 2, 3, 4, 0, 6, 7, 8, 9,
10, 11, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 340, 12, 13, 14, 15, 16, 17, 18,
+ 0, 0, 268, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
0, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 0, 42, 43, 44, 0, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 0,
- 55, 56, 57, 58, 0, 59, 1, 2, 3, 4,
+ 38, 39, 40, 41, 0, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 0,
+ 56, 57, 58, 59, 0, 60, 0, 0, 0, 0,
+ 0, 0, 0, 113, 0, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 341, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 0, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 0,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 59, 0,
+ 60, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 0, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 0, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 0,
+ 56, 57, 58, 59, 0, 60, 134, 2, 3, 4,
+ 0, 6, 7, 8, 9, 10, 11, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 0, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 0,
- 42, 43, 44, 0, 45, 46, 47, 48, 49, 50,
- 51, 52, 53, 54, 0, 55, 56, 57, 58, 0,
- 59, 133, 2, 3, 4, 0, 6, 7, 8, 9,
- 10, 11, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
- 0, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, 0, 42, 43, 44, 0, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 0,
- 55, 56, 57, 58, 0, 59, 2, 3, 4, 0,
- 0, 0, 8, 9, 10, 11, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 0, 0, 0, 0, 0, 31, 32, 33,
- 34, 35, 36, 0, 0, 0, 40, 41, 0, 42,
- 43, 44, 0, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 0, 55, 56, 57, 0, 0, 59,
- 8, 9, 10, 11, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 0, 0, 0, 0, 0, 31, 32, 33, 34, 35,
- 36, 0, 0, 0, 40, 41, 0, 42, 43, 44,
- 0, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 0, 55, 56, 57, 0, 316, 59, 8, 9,
- 10, 11, 317, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 0, 0,
- 0, 0, 0, 31, 32, 33, 34, 35, 36, 0,
- 0, 0, 40, 41, 0, 42, 43, 44, 0, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 0,
- 55, 56, 57, 0, 0, 59
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 59, 0,
+ 60, 2, 3, 4, 0, 0, 0, 8, 9, 10,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 0, 0, 0,
+ 0, 0, 31, 32, 33, 34, 35, 36, 0, 0,
+ 0, 40, 41, 0, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 0, 56,
+ 57, 58, 0, 0, 60, 8, 9, 10, 11, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 0, 0, 0, 0, 0,
+ 31, 32, 33, 34, 35, 36, 0, 0, 0, 40,
+ 41, 0, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 0, 56, 57, 58,
+ 0, 317, 60, 8, 9, 10, 11, 318, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 0, 0, 0, 0, 0, 31, 32,
+ 33, 34, 35, 36, 0, 0, 0, 40, 41, 0,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 0, 56, 57, 58, 0, 0,
+ 60
};
static const yytype_int16 yycheck[] =
{
- 0, 69, 146, 209, 131, 91, 107, 111, 1, 1,
- 9, 130, 220, 136, 0, 343, 117, 0, 76, 9,
- 117, 106, 104, 92, 349, 104, 130, 106, 76, 114,
- 106, 99, 105, 160, 113, 136, 114, 113, 371, 107,
- 111, 40, 41, 42, 76, 370, 190, 83, 84, 117,
- 40, 41, 111, 43, 44, 114, 114, 180, 127, 127,
- 108, 51, 52, 53, 105, 393, 134, 400, 136, 69,
- 111, 399, 72, 192, 116, 68, 118, 77, 179, 180,
- 73, 105, 179, 106, 84, 76, 76, 111, 192, 82,
- 105, 77, 236, 220, 77, 105, 111, 305, 76, 99,
- 219, 111, 87, 88, 85, 86, 105, 107, 105, 40,
- 41, 179, 180, 240, 111, 219, 9, 117, 105, 108,
- 264, 121, 9, 111, 111, 106, 114, 127, 108, 110,
- 9, 275, 89, 90, 134, 279, 136, 122, 123, 111,
- 133, 133, 114, 266, 350, 108, 354, 40, 41, 357,
- 43, 44, 111, 40, 41, 114, 43, 113, 51, 52,
- 53, 40, 41, 42, 51, 266, 79, 80, 111, 296,
- 297, 114, 380, 4, 5, 6, 114, 111, 305, 179,
- 180, 76, 301, 111, 112, 252, 253, 254, 255, 308,
- 40, 41, 42, 76, 402, 104, 130, 301, 266, 119,
- 120, 121, 248, 249, 308, 349, 250, 251, 105, 209,
- 144, 145, 94, 95, 96, 97, 98, 99, 100, 101,
- 102, 103, 256, 257, 104, 126, 370, 354, 124, 163,
- 357, 113, 91, 125, 107, 93, 114, 364, 114, 104,
- 104, 385, 361, 114, 104, 112, 109, 104, 349, 104,
- 106, 113, 106, 380, 398, 107, 342, 361, 192, 105,
- 108, 112, 107, 107, 113, 104, 266, 56, 104, 370,
- 113, 111, 107, 107, 76, 402, 113, 105, 107, 109,
- 105, 114, 17, 237, 284, 219, 108, 113, 258, 260,
- 114, 114, 259, 261, 263, 127, 262, 93, 5, 100,
- 127, 225, 183, 309, 344, 399, 344, 375, 391, 284,
- 370, 245, 246, 247, 248, 249, 250, 251, 252, 253,
- 254, 255, 256, 257, 258, 259, 260, 261, 262, 263,
- 77, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 343, 344, -1, -1, -1, -1, 349,
- 350, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 301, -1, -1,
- 370, -1, -1, -1, 308, 375, -1, -1, -1, -1,
+ 0, 70, 112, 108, 132, 92, 221, 210, 1, 147,
+ 9, 0, 131, 118, 1, 118, 137, 0, 76, 9,
+ 104, 131, 111, 9, 350, 114, 87, 88, 92, 372,
+ 344, 100, 137, 161, 111, 76, 106, 114, 104, 108,
+ 106, 40, 41, 42, 114, 371, 114, 113, 105, 118,
+ 40, 41, 42, 191, 40, 41, 114, 43, 401, 128,
+ 181, 122, 123, 127, 106, 51, 135, 108, 137, 114,
+ 70, 113, 111, 73, 193, 180, 181, 180, 78, 116,
+ 394, 118, 69, 193, 105, 85, 400, 74, 105, 78,
+ 111, 306, 105, 221, 111, 78, 83, 105, 111, 237,
+ 100, 220, 111, 111, 111, 114, 105, 114, 108, 105,
+ 220, 180, 181, 241, 105, 111, 111, 76, 118, 114,
+ 111, 106, 122, 76, 85, 86, 108, 265, 128, 9,
+ 253, 254, 255, 256, 108, 135, 76, 137, 276, 108,
+ 355, 134, 280, 358, 76, 106, 267, 134, 351, 110,
+ 4, 5, 6, 40, 41, 42, 119, 120, 121, 113,
+ 40, 41, 267, 43, 44, 76, 381, 40, 41, 297,
+ 298, 51, 52, 53, 83, 84, 89, 90, 306, 105,
+ 180, 181, 112, 302, 79, 80, 111, 112, 403, 104,
+ 309, 126, 302, 249, 250, 124, 76, 9, 267, 309,
+ 104, 131, 251, 252, 257, 258, 125, 91, 93, 107,
+ 210, 114, 350, 114, 104, 145, 146, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 355, 40, 41,
+ 358, 43, 44, 371, 164, 104, 113, 365, 114, 51,
+ 52, 53, 104, 362, 112, 350, 104, 104, 386, 109,
+ 106, 106, 362, 381, 113, 107, 343, 105, 108, 112,
+ 107, 399, 113, 193, 113, 107, 371, 267, 111, 104,
+ 56, 107, 113, 107, 104, 403, 76, 105, 109, 105,
+ 107, 114, 17, 108, 113, 285, 238, 259, 261, 260,
+ 220, 114, 114, 263, 262, 94, 128, 264, 101, 5,
+ 310, 184, 226, 400, 128, 345, 392, 376, 285, 345,
+ 78, 371, -1, -1, -1, -1, 246, 247, 248, 249,
+ 250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
+ 260, 261, 262, 263, 264, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 344, 345, -1, -1, -1, -1,
+ 350, 351, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 393, -1, -1, -1, -1, -1, 399,
+ -1, 371, 302, -1, -1, -1, 376, -1, -1, 309,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 361, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, -1, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- -1, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, -1, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, -1, -1, 85, 86, -1, -1, -1,
+ -1, -1, -1, -1, 394, -1, -1, -1, -1, -1,
+ 400, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 362, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, -1, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, -1, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, -1, -1,
+ 85, 86, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 104,
+ -1, -1, -1, 108, 109, -1, -1, -1, -1, 114,
+ 115, 116, 117, 118, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, -1, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, -1, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, -1, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, -1, -1, 85, 86, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 104, -1, -1, -1, 108, 109,
- -1, -1, -1, -1, 114, 115, 116, 117, 118, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, -1, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, -1, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, -1, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, -1, 72, 73,
- 74, 75, 76, 77, 78, 79, 80, 81, 82, -1,
- -1, 85, 86, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 104, -1, -1, -1, 108, 109, -1, -1, -1, -1,
- 114, 115, 116, 117, 118, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15, 16, -1,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40, 41, -1, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, -1, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, -1, 72, 73, 74, 75, 76, 77,
- 78, 79, 80, 81, 82, -1, -1, 85, 86, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 104, -1, -1, -1,
- 108, -1, -1, -1, -1, -1, 114, 115, 116, 117,
- 118, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, -1, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
- -1, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, -1, 61,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, -1,
- 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
- 82, -1, -1, 85, 86, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 104, -1, -1, -1, 108, -1, -1, -1,
- -1, -1, 114, 115, 116, 117, 118, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, -1, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, -1, 43, 44, 45,
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, -1, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, -1, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, 82, -1, -1, 85,
- 86, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 104, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 114, 115,
- 116, 117, 118, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, -1, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, -1, 57, 58, 59,
- -1, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, -1, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, -1, -1, 85, 86, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 3, 4, 5, 6, 104, 8, 9, 10, 11, 12,
- 13, -1, -1, -1, 114, 115, 116, 117, 118, -1,
- -1, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ -1, -1, -1, -1, -1, 104, -1, -1, -1, 108,
+ 109, -1, -1, -1, -1, 114, 115, 116, 117, 118,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, -1, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, -1,
43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, 54, 55, -1, 57, 58, 59, -1, 61, 62,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
63, 64, 65, 66, 67, 68, 69, 70, -1, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
-1, -1, 85, 86, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 4, 5, 6, -1,
- -1, 104, 10, 11, 12, 13, -1, -1, -1, -1,
- -1, -1, 115, 116, 117, 118, -1, 25, 26, 27,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 104, -1, -1, -1, 108, -1, -1, -1, -1,
+ -1, 114, 115, 116, 117, 118, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ -1, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, -1, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, -1, -1, 85, 86,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 104, -1, -1,
+ -1, 108, -1, -1, -1, -1, -1, 114, 115, 116,
+ 117, 118, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, -1, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, -1, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ -1, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, -1, -1, 85, 86, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 104, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 114, 115, 116, 117, 118, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, -1, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, -1, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, -1, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, -1, -1,
+ 85, 86, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 3, 4, 5, 6, 104,
+ 8, 9, 10, 11, 12, 13, -1, -1, -1, 114,
+ 115, 116, 117, 118, -1, -1, -1, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, -1, -1, -1, -1, -1, 45, 46, 47,
- 48, 49, 50, -1, -1, -1, 54, 55, -1, 57,
- 58, 59, -1, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, -1, 72, 73, 74, -1, 76, 77,
- -1, -1, 10, 11, 12, 13, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, -1, -1, -1, -1, 114, 45, 46, 47,
- 48, 49, 50, -1, -1, -1, 54, 55, -1, 57,
- 58, 59, -1, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, -1, 72, 73, 74, -1, 76, 77,
+ 38, 39, 40, 41, -1, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, -1, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, -1, 72, 73, 74, 75, 76, 77,
78, 79, 80, 81, 82, -1, -1, 85, 86, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 104, -1, -1, 107,
- 10, 11, 12, 13, -1, -1, -1, 115, 116, 117,
- 118, -1, -1, -1, -1, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- -1, -1, -1, -1, -1, 45, 46, 47, 48, 49,
- 50, -1, -1, -1, 54, 55, -1, 57, 58, 59,
- -1, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, -1, 72, 73, 74, -1, 76, 77, 78, 79,
- 80, 81, 82, -1, -1, 85, 86, -1, -1, -1,
+ -1, 4, 5, 6, -1, -1, 104, 10, 11, 12,
+ 13, -1, -1, -1, -1, -1, -1, 115, 116, 117,
+ 118, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
+ -1, -1, 45, 46, 47, 48, 49, 50, -1, -1,
+ -1, 54, 55, -1, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, -1, 72,
+ 73, 74, -1, 76, 77, -1, -1, 10, 11, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
+ -1, 114, 45, 46, 47, 48, 49, 50, -1, -1,
+ -1, 54, 55, -1, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, -1, 72,
+ 73, 74, -1, 76, 77, 78, 79, 80, 81, 82,
+ -1, -1, 85, 86, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 104, -1, -1, 107, 10, 11,
- 12, 13, -1, -1, -1, 115, 116, 117, 118, -1,
- -1, -1, -1, 25, 26, 27, 28, 29, 30, 31,
+ -1, 104, -1, -1, 107, 10, 11, 12, 13, -1,
+ -1, -1, 115, 116, 117, 118, -1, -1, -1, -1,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, -1, -1, -1, -1, -1,
+ 45, 46, 47, 48, 49, 50, -1, -1, -1, 54,
+ 55, -1, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, -1, 72, 73, 74,
+ -1, 76, 77, 78, 79, 80, 81, 82, -1, -1,
+ 85, 86, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 104,
+ -1, -1, 107, 10, 11, 12, 13, -1, -1, -1,
+ 115, 116, 117, 118, -1, -1, -1, -1, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, -1, -1, -1, -1, -1, 45, 46,
+ 47, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, -1, 76,
+ 77, 78, 79, 80, 81, 82, -1, -1, 85, 86,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 104, 10, 11,
+ 12, 13, -1, -1, -1, -1, -1, 114, 115, 116,
+ 117, 118, -1, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, -1, -1,
-1, -1, -1, 45, 46, 47, 48, 49, 50, -1,
- -1, -1, 54, 55, -1, 57, 58, 59, -1, 61,
+ -1, -1, 54, 55, -1, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, -1,
72, 73, 74, -1, 76, 77, 78, 79, 80, 81,
82, -1, -1, 85, 86, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 104, 10, 11, 12, 13, -1, -1, -1,
- -1, -1, 114, 115, 116, 117, 118, -1, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, -1, -1, -1, -1, -1, 45, 46,
- 47, 48, 49, 50, -1, -1, -1, 54, 55, -1,
- 57, 58, 59, -1, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, -1, 72, 73, 74, -1, 76,
- 77, 78, 79, 80, 81, 82, -1, -1, 85, 86,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 104, -1, -1,
- 107, 10, 11, 12, 13, -1, -1, -1, 115, 116,
- 117, 118, -1, -1, -1, -1, 25, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, -1, -1, -1, -1, -1, 45, 46, 47, 48,
- 49, 50, -1, -1, -1, 54, 55, -1, 57, 58,
- 59, -1, 61, 62, 63, 64, 65, 66, 67, 68,
- 69, 70, -1, 72, 73, 74, -1, 76, 77, 78,
- 79, 80, 81, 82, -1, -1, 85, 86, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 104, 10, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, 115, 116, 117, 118,
+ -1, -1, 104, -1, -1, 107, 10, 11, 12, 13,
+ -1, -1, -1, 115, 116, 117, 118, -1, -1, -1,
-1, 25, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, -1, -1, -1, -1,
-1, 45, 46, 47, 48, 49, 50, -1, -1, -1,
- 54, 55, -1, 57, 58, 59, -1, 61, 62, 63,
+ 54, 55, -1, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, -1, 72, 73,
74, -1, 76, 77, 78, 79, 80, 81, 82, -1,
-1, 85, 86, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 3, 4, 5, 6,
- 104, 8, 9, 10, 11, 12, 13, -1, -1, -1,
- -1, 115, 116, 117, 118, -1, -1, -1, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, -1, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, -1,
- 57, 58, 59, -1, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, -1, 72, 73, 74, 75, -1,
- 77, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 3, 4, 5, 6, -1, 8, 9, 10, 11,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 109, 25, 26, 27, 28, 29, 30, 31,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 104, 10, 11, 12, 13, -1, -1, -1, -1, -1,
+ -1, 115, 116, 117, 118, -1, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, -1, -1, -1, -1, -1, 45, 46, 47, 48,
+ 49, 50, -1, -1, -1, 54, 55, -1, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, -1, 72, 73, 74, -1, 76, 77, 78,
+ 79, 80, 81, 82, -1, -1, 85, 86, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 3, 4, 5, 6, 104, 8, 9, 10, 11,
+ 12, 13, -1, -1, -1, -1, 115, 116, 117, 118,
+ -1, -1, -1, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
-1, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, -1, 57, 58, 59, -1, 61,
+ 52, 53, 54, 55, -1, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, -1,
72, 73, 74, 75, -1, 77, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 3, 4, 5, 6,
@@ -1425,53 +1418,62 @@
27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, -1, 43, 44, 45, 46,
47, 48, 49, 50, 51, 52, 53, 54, 55, -1,
- 57, 58, 59, -1, 61, 62, 63, 64, 65, 66,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
67, 68, 69, 70, -1, 72, 73, 74, 75, -1,
- 77, -1, -1, -1, -1, -1, -1, -1, 0, -1,
- -1, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 77, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 3, 4, 5, 6, -1, 8, 9, 10, 11,
12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 109, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
-1, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, -1, 57, 58, 59, -1, 61,
+ 52, 53, 54, 55, -1, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, -1,
- 72, 73, 74, 75, -1, 77, 3, 4, 5, 6,
+ 72, 73, 74, 75, -1, 77, -1, -1, -1, -1,
+ -1, -1, -1, 0, -1, -1, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 25, 26,
+ -1, -1, -1, -1, -1, -1, -1, 109, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, -1, 43, 44, 45, 46,
47, 48, 49, 50, 51, 52, 53, 54, 55, -1,
- 57, 58, 59, -1, 61, 62, 63, 64, 65, 66,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
67, 68, 69, 70, -1, 72, 73, 74, 75, -1,
- 77, 3, 4, 5, 6, -1, 8, 9, 10, 11,
+ 77, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
-1, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, -1, 57, 58, 59, -1, 61,
+ 52, 53, 54, 55, -1, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, -1,
- 72, 73, 74, 75, -1, 77, 4, 5, 6, -1,
- -1, -1, 10, 11, 12, 13, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, -1, -1, -1, -1, -1, 45, 46, 47,
- 48, 49, 50, -1, -1, -1, 54, 55, -1, 57,
- 58, 59, -1, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, -1, 72, 73, 74, -1, -1, 77,
- 10, 11, 12, 13, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- -1, -1, -1, -1, -1, 45, 46, 47, 48, 49,
- 50, -1, -1, -1, 54, 55, -1, 57, 58, 59,
- -1, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, -1, 72, 73, 74, -1, 76, 77, 10, 11,
- 12, 13, 82, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, -1, -1,
- -1, -1, -1, 45, 46, 47, 48, 49, 50, -1,
- -1, -1, 54, 55, -1, 57, 58, 59, -1, 61,
- 62, 63, 64, 65, 66, 67, 68, 69, 70, -1,
- 72, 73, 74, -1, -1, 77
+ 72, 73, 74, 75, -1, 77, 3, 4, 5, 6,
+ -1, 8, 9, 10, 11, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, -1, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, -1,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, 75, -1,
+ 77, 4, 5, 6, -1, -1, -1, 10, 11, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
+ -1, -1, 45, 46, 47, 48, 49, 50, -1, -1,
+ -1, 54, 55, -1, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, -1, 72,
+ 73, 74, -1, -1, 77, 10, 11, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, -1, -1, -1, -1, -1,
+ 45, 46, 47, 48, 49, 50, -1, -1, -1, 54,
+ 55, -1, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, -1, 72, 73, 74,
+ -1, 76, 77, 10, 11, 12, 13, 82, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, -1, -1, -1, -1, -1, 45, 46,
+ 47, 48, 49, 50, -1, -1, -1, 54, 55, -1,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, -1, -1,
+ 77
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1482,44 +1484,44 @@
12, 13, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 43,
44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 57, 58, 59, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 72, 73, 74, 75, 77,
- 159, 160, 161, 162, 163, 168, 169, 170, 171, 173,
- 174, 175, 176, 177, 180, 181, 182, 217, 218, 219,
- 44, 76, 171, 174, 176, 40, 41, 76, 108, 104,
- 114, 220, 105, 111, 9, 40, 41, 42, 165, 166,
- 172, 111, 114, 76, 174, 76, 114, 158, 175, 180,
- 174, 106, 0, 218, 174, 180, 108, 184, 76, 178,
- 179, 108, 200, 165, 164, 167, 175, 166, 76, 104,
- 106, 113, 108, 3, 173, 175, 185, 186, 76, 78,
- 79, 80, 81, 82, 85, 86, 104, 107, 115, 116,
- 117, 118, 129, 130, 131, 133, 134, 135, 136, 137,
- 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,
- 148, 149, 150, 151, 152, 153, 157, 180, 114, 183,
- 185, 113, 105, 111, 14, 15, 16, 18, 19, 20,
- 21, 22, 23, 24, 56, 108, 109, 114, 140, 153,
- 154, 156, 159, 160, 180, 190, 191, 192, 193, 201,
- 202, 203, 205, 207, 209, 216, 76, 164, 167, 106,
- 113, 107, 157, 154, 189, 175, 76, 187, 188, 109,
- 186, 140, 140, 156, 85, 86, 106, 110, 105, 105,
- 111, 55, 154, 104, 140, 119, 120, 121, 116, 118,
- 83, 84, 87, 88, 122, 123, 89, 90, 126, 125,
- 124, 91, 93, 92, 127, 107, 185, 109, 79, 80,
- 179, 114, 114, 211, 104, 104, 114, 114, 156, 104,
- 157, 112, 104, 109, 194, 94, 95, 96, 97, 98,
- 99, 100, 101, 102, 103, 113, 155, 111, 114, 109,
- 191, 106, 107, 157, 189, 113, 107, 187, 106, 111,
- 114, 76, 114, 105, 132, 156, 76, 82, 135, 154,
- 140, 140, 140, 142, 142, 143, 143, 144, 144, 144,
- 144, 145, 145, 146, 147, 148, 149, 150, 151, 156,
- 109, 197, 198, 199, 212, 156, 114, 156, 112, 210,
- 201, 154, 154, 157, 113, 107, 189, 113, 114, 157,
- 188, 106, 114, 107, 112, 56, 200, 192, 190, 202,
- 213, 105, 105, 156, 170, 173, 208, 195, 107, 189,
- 113, 189, 107, 157, 154, 104, 208, 214, 215, 197,
- 204, 206, 76, 105, 109, 189, 107, 156, 114, 105,
- 17, 193, 113, 192, 196, 200, 114, 105, 156, 196,
- 197, 189, 114
+ 54, 55, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 72, 73, 74, 75,
+ 77, 159, 160, 161, 162, 163, 168, 169, 170, 171,
+ 173, 174, 175, 176, 177, 180, 181, 182, 217, 218,
+ 219, 44, 76, 171, 174, 176, 40, 41, 76, 108,
+ 104, 114, 220, 105, 111, 9, 40, 41, 42, 165,
+ 166, 172, 111, 114, 76, 174, 76, 114, 158, 175,
+ 180, 174, 106, 0, 218, 174, 180, 108, 184, 76,
+ 178, 179, 108, 200, 165, 164, 167, 175, 166, 76,
+ 104, 106, 113, 108, 3, 173, 175, 185, 186, 76,
+ 78, 79, 80, 81, 82, 85, 86, 104, 107, 115,
+ 116, 117, 118, 129, 130, 131, 133, 134, 135, 136,
+ 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, 152, 153, 157, 180, 114,
+ 183, 185, 113, 105, 111, 14, 15, 16, 18, 19,
+ 20, 21, 22, 23, 24, 56, 108, 109, 114, 140,
+ 153, 154, 156, 159, 160, 180, 190, 191, 192, 193,
+ 201, 202, 203, 205, 207, 209, 216, 76, 164, 167,
+ 106, 113, 107, 157, 154, 189, 175, 76, 187, 188,
+ 109, 186, 140, 140, 156, 85, 86, 106, 110, 105,
+ 105, 111, 55, 154, 104, 140, 119, 120, 121, 116,
+ 118, 83, 84, 87, 88, 122, 123, 89, 90, 126,
+ 125, 124, 91, 93, 92, 127, 107, 185, 109, 79,
+ 80, 179, 114, 114, 211, 104, 104, 114, 114, 156,
+ 104, 157, 112, 104, 109, 194, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 113, 155, 111, 114,
+ 109, 191, 106, 107, 157, 189, 113, 107, 187, 106,
+ 111, 114, 76, 114, 105, 132, 156, 76, 82, 135,
+ 154, 140, 140, 140, 142, 142, 143, 143, 144, 144,
+ 144, 144, 145, 145, 146, 147, 148, 149, 150, 151,
+ 156, 109, 197, 198, 199, 212, 156, 114, 156, 112,
+ 210, 201, 154, 154, 157, 113, 107, 189, 113, 114,
+ 157, 188, 106, 114, 107, 112, 56, 200, 192, 190,
+ 202, 213, 105, 105, 156, 170, 173, 208, 195, 107,
+ 189, 113, 189, 107, 157, 154, 104, 208, 214, 215,
+ 197, 204, 206, 76, 105, 109, 189, 107, 156, 114,
+ 105, 17, 193, 113, 192, 196, 200, 114, 105, 156,
+ 196, 197, 189, 114
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
@@ -1545,14 +1547,14 @@
181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
- 181, 181, 183, 182, 184, 182, 185, 185, 186, 186,
- 187, 187, 188, 188, 189, 190, 191, 191, 192, 192,
- 192, 192, 192, 192, 192, 193, 194, 195, 193, 196,
- 196, 198, 197, 199, 197, 200, 200, 201, 201, 202,
- 202, 203, 204, 204, 206, 205, 207, 207, 208, 208,
- 210, 209, 211, 209, 212, 209, 213, 213, 214, 214,
- 215, 215, 216, 216, 216, 216, 216, 217, 217, 218,
- 218, 220, 219
+ 181, 181, 181, 183, 182, 184, 182, 185, 185, 186,
+ 186, 187, 187, 188, 188, 189, 190, 191, 191, 192,
+ 192, 192, 192, 192, 192, 192, 193, 194, 195, 193,
+ 196, 196, 198, 197, 199, 197, 200, 200, 201, 201,
+ 202, 202, 203, 204, 204, 206, 205, 207, 207, 208,
+ 208, 210, 209, 211, 209, 212, 209, 213, 213, 214,
+ 214, 215, 215, 216, 216, 216, 216, 216, 217, 217,
+ 218, 218, 220, 219
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -1578,14 +1580,14 @@
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 6, 0, 5, 1, 2, 3, 4,
- 1, 3, 1, 4, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 2, 0, 0, 5, 1,
- 1, 0, 2, 0, 2, 2, 3, 1, 2, 1,
- 2, 5, 3, 1, 0, 6, 3, 2, 1, 4,
- 0, 6, 0, 8, 0, 7, 1, 1, 1, 0,
- 2, 3, 2, 2, 2, 3, 2, 1, 2, 1,
- 1, 0, 3
+ 1, 1, 1, 0, 6, 0, 5, 1, 2, 3,
+ 4, 1, 3, 1, 4, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 0, 0, 5,
+ 1, 1, 0, 2, 0, 2, 2, 3, 1, 2,
+ 1, 2, 5, 3, 1, 0, 6, 3, 2, 1,
+ 4, 0, 6, 0, 8, 0, 7, 1, 1, 1,
+ 0, 2, 3, 2, 2, 2, 3, 2, 1, 2,
+ 1, 1, 0, 3
};
@@ -2373,8 +2375,9 @@
// don't delete $1.string, it's used by error recovery, and the pool
// pop will reclaim the memory
+ // Constants which aren't indexable arrays can be propagated by value.
ConstantUnion *constArray = variable->getConstPointer();
- if (constArray) {
+ if (constArray && variable->getType().getArraySize() <= 1) {
TType t(variable->getType());
(yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(constArray, t, (yylsp[0]));
} else
@@ -4123,6 +4126,20 @@
case 187:
{
+ if (!context->supportsExtension("GL_ARB_texture_rectangle")) {
+ context->error((yylsp[0]), "unsupported type", "sampler2DRect", "");
+ context->recover();
+ }
+ FRAG_VERT_ONLY("sampler2DRect", (yylsp[0]));
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSampler2DRect, qual, (yylsp[0]));
+ }
+
+ break;
+
+ case 188:
+
+ {
FRAG_VERT_ONLY("sampler3D", (yylsp[0]));
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
(yyval.interm.type).setBasic(EbtSampler3D, qual, (yylsp[0]));
@@ -4130,7 +4147,7 @@
break;
- case 188:
+ case 189:
{
FRAG_VERT_ONLY("sampler2DArray", (yylsp[0]));
@@ -4140,7 +4157,7 @@
break;
- case 189:
+ case 190:
{
FRAG_VERT_ONLY("isampler2D", (yylsp[0]));
@@ -4150,7 +4167,7 @@
break;
- case 190:
+ case 191:
{
FRAG_VERT_ONLY("isampler3D", (yylsp[0]));
@@ -4160,7 +4177,7 @@
break;
- case 191:
+ case 192:
{
FRAG_VERT_ONLY("isamplerCube", (yylsp[0]));
@@ -4170,7 +4187,7 @@
break;
- case 192:
+ case 193:
{
FRAG_VERT_ONLY("isampler2DArray", (yylsp[0]));
@@ -4180,7 +4197,7 @@
break;
- case 193:
+ case 194:
{
FRAG_VERT_ONLY("usampler2D", (yylsp[0]));
@@ -4190,7 +4207,7 @@
break;
- case 194:
+ case 195:
{
FRAG_VERT_ONLY("usampler3D", (yylsp[0]));
@@ -4200,7 +4217,7 @@
break;
- case 195:
+ case 196:
{
FRAG_VERT_ONLY("usamplerCube", (yylsp[0]));
@@ -4210,7 +4227,7 @@
break;
- case 196:
+ case 197:
{
FRAG_VERT_ONLY("usampler2DArray", (yylsp[0]));
@@ -4220,7 +4237,7 @@
break;
- case 197:
+ case 198:
{
FRAG_VERT_ONLY("sampler2DShadow", (yylsp[0]));
@@ -4230,7 +4247,7 @@
break;
- case 198:
+ case 199:
{
FRAG_VERT_ONLY("samplerCubeShadow", (yylsp[0]));
@@ -4240,7 +4257,7 @@
break;
- case 199:
+ case 200:
{
FRAG_VERT_ONLY("sampler2DArrayShadow", (yylsp[0]));
@@ -4250,7 +4267,7 @@
break;
- case 200:
+ case 201:
{
FRAG_VERT_ONLY("struct", (yylsp[0]));
@@ -4260,7 +4277,7 @@
break;
- case 201:
+ case 202:
{
//
@@ -4275,13 +4292,13 @@
break;
- case 202:
+ case 203:
{ if (context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string)) context->recover(); }
break;
- case 203:
+ case 204:
{
(yyval.interm.type) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList));
@@ -4289,13 +4306,13 @@
break;
- case 204:
+ case 205:
{ if (context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string)) context->recover(); }
break;
- case 205:
+ case 206:
{
(yyval.interm.type) = context->addStructure((yylsp[-4]), (yylsp[-4]), NewPoolTString(""), (yyvsp[-1].interm.fieldList));
@@ -4303,7 +4320,7 @@
break;
- case 206:
+ case 207:
{
(yyval.interm.fieldList) = (yyvsp[0].interm.fieldList);
@@ -4311,7 +4328,7 @@
break;
- case 207:
+ case 208:
{
(yyval.interm.fieldList) = (yyvsp[-1].interm.fieldList);
@@ -4329,7 +4346,7 @@
break;
- case 208:
+ case 209:
{
(yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList));
@@ -4337,7 +4354,7 @@
break;
- case 209:
+ case 210:
{
// ES3 Only, but errors should be handled elsewhere
@@ -4348,7 +4365,7 @@
break;
- case 210:
+ case 211:
{
(yyval.interm.fieldList) = NewPoolTFieldList();
@@ -4357,7 +4374,7 @@
break;
- case 211:
+ case 212:
{
(yyval.interm.fieldList)->push_back((yyvsp[0].interm.field));
@@ -4365,7 +4382,7 @@
break;
- case 212:
+ case 213:
{
if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string))
@@ -4377,7 +4394,7 @@
break;
- case 213:
+ case 214:
{
if (context->reservedErrorCheck((yylsp[-3]), *(yyvsp[-3].lex).string))
@@ -4394,27 +4411,21 @@
break;
- case 214:
+ case 215:
{ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); }
break;
- case 215:
-
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
-
- break;
-
case 216:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
case 217:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
break;
@@ -4438,19 +4449,19 @@
case 221:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
case 222:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch); }
break;
case 223:
- { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase); }
break;
@@ -4462,24 +4473,30 @@
case 225:
- { (yyval.interm.intermAggregate) = 0; }
+ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
case 226:
- { context->symbolTable.push(); }
+ { (yyval.interm.intermAggregate) = 0; }
break;
case 227:
- { context->symbolTable.pop(); }
+ { context->symbolTable.push(); }
break;
case 228:
+ { context->symbolTable.pop(); }
+
+ break;
+
+ case 229:
+
{
if ((yyvsp[-2].interm.intermAggregate) != 0) {
(yyvsp[-2].interm.intermAggregate)->setOp(EOpSequence);
@@ -4490,51 +4507,51 @@
break;
- case 229:
+ case 230:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
break;
- case 230:
+ case 231:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
break;
- case 231:
-
- { context->symbolTable.push(); }
-
- break;
-
case 232:
- { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
+ { context->symbolTable.push(); }
break;
case 233:
- { context->symbolTable.push(); }
+ { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
break;
case 234:
- { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+ { context->symbolTable.push(); }
break;
case 235:
+ { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); }
+
+ break;
+
+ case 236:
+
{
(yyval.interm.intermAggregate) = 0;
}
break;
- case 236:
+ case 237:
{
if ((yyvsp[-1].interm.intermAggregate)) {
@@ -4546,7 +4563,7 @@
break;
- case 237:
+ case 238:
{
(yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[0].interm.intermNode), (yyloc));
@@ -4554,7 +4571,7 @@
break;
- case 238:
+ case 239:
{
(yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[-1].interm.intermAggregate), (yyvsp[0].interm.intermNode), (yyloc));
@@ -4562,19 +4579,19 @@
break;
- case 239:
+ case 240:
{ (yyval.interm.intermNode) = 0; }
break;
- case 240:
+ case 241:
{ (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[-1].interm.intermTypedNode)); }
break;
- case 241:
+ case 242:
{
if (context->boolErrorCheck((yylsp[-4]), (yyvsp[-2].interm.intermTypedNode)))
@@ -4584,7 +4601,7 @@
break;
- case 242:
+ case 243:
{
(yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
@@ -4593,7 +4610,7 @@
break;
- case 243:
+ case 244:
{
(yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode);
@@ -4602,13 +4619,13 @@
break;
- case 244:
+ case 245:
{ context->incrSwitchNestingLevel(); }
break;
- case 245:
+ case 246:
{
(yyval.interm.intermSwitch) = context->addSwitch((yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermAggregate), (yylsp[-5]));
@@ -4617,7 +4634,7 @@
break;
- case 246:
+ case 247:
{
(yyval.interm.intermCase) = context->addCase((yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
@@ -4625,7 +4642,7 @@
break;
- case 247:
+ case 248:
{
(yyval.interm.intermCase) = context->addDefault((yylsp[-1]));
@@ -4633,7 +4650,7 @@
break;
- case 248:
+ case 249:
{
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
@@ -4643,7 +4660,7 @@
break;
- case 249:
+ case 250:
{
TIntermNode *intermNode;
@@ -4660,13 +4677,13 @@
break;
- case 250:
+ case 251:
{ context->symbolTable.push(); context->incrLoopNestingLevel(); }
break;
- case 251:
+ case 252:
{
context->symbolTable.pop();
@@ -4676,13 +4693,13 @@
break;
- case 252:
+ case 253:
{ context->incrLoopNestingLevel(); }
break;
- case 253:
+ case 254:
{
if (context->boolErrorCheck((yylsp[0]), (yyvsp[-2].interm.intermTypedNode)))
@@ -4694,26 +4711,18 @@
break;
- case 254:
-
- { context->symbolTable.push(); context->incrLoopNestingLevel(); }
-
- break;
-
case 255:
- {
- context->symbolTable.pop();
- (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[-3].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[-2].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[-2].interm.nodePair).node2), (yyvsp[0].interm.intermNode), (yylsp[-6]));
- context->decrLoopNestingLevel();
- }
+ { context->symbolTable.push(); context->incrLoopNestingLevel(); }
break;
case 256:
{
- (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[-3].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[-2].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[-2].interm.nodePair).node2), (yyvsp[0].interm.intermNode), (yylsp[-6]));
+ context->decrLoopNestingLevel();
}
break;
@@ -4729,7 +4738,7 @@
case 258:
{
- (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
}
break;
@@ -4737,7 +4746,7 @@
case 259:
{
- (yyval.interm.intermTypedNode) = 0;
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
}
break;
@@ -4745,13 +4754,21 @@
case 260:
{
+ (yyval.interm.intermTypedNode) = 0;
+ }
+
+ break;
+
+ case 261:
+
+ {
(yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode);
(yyval.interm.nodePair).node2 = 0;
}
break;
- case 261:
+ case 262:
{
(yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode);
@@ -4760,7 +4777,7 @@
break;
- case 262:
+ case 263:
{
(yyval.interm.intermNode) = context->addBranch(EOpContinue, (yylsp[-1]));
@@ -4768,7 +4785,7 @@
break;
- case 263:
+ case 264:
{
(yyval.interm.intermNode) = context->addBranch(EOpBreak, (yylsp[-1]));
@@ -4776,7 +4793,7 @@
break;
- case 264:
+ case 265:
{
(yyval.interm.intermNode) = context->addBranch(EOpReturn, (yylsp[-1]));
@@ -4784,7 +4801,7 @@
break;
- case 265:
+ case 266:
{
(yyval.interm.intermNode) = context->addBranch(EOpReturn, (yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
@@ -4792,7 +4809,7 @@
break;
- case 266:
+ case 267:
{
FRAG_ONLY("discard", (yylsp[-1]));
@@ -4801,19 +4818,10 @@
break;
- case 267:
-
- {
- (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
- context->setTreeRoot((yyval.interm.intermNode));
- }
-
- break;
-
case 268:
{
- (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode), (yyloc));
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
context->setTreeRoot((yyval.interm.intermNode));
}
@@ -4822,7 +4830,8 @@
case 269:
{
- (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode), (yyloc));
+ context->setTreeRoot((yyval.interm.intermNode));
}
break;
@@ -4838,7 +4847,7 @@
case 271:
{
- context->parseFunctionPrototype((yylsp[0]), (yyvsp[0].interm).function, &(yyvsp[0].interm).intermAggregate);
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
}
break;
@@ -4846,6 +4855,14 @@
case 272:
{
+ context->parseFunctionPrototype((yylsp[0]), (yyvsp[0].interm).function, &(yyvsp[0].interm).intermAggregate);
+ }
+
+ break;
+
+ case 273:
+
+ {
(yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermAggregate), (yylsp[-2]));
}
diff --git a/src/OpenGL/compiler/intermediate.h b/src/OpenGL/compiler/intermediate.h
index 7757d89..d277255 100644
--- a/src/OpenGL/compiler/intermediate.h
+++ b/src/OpenGL/compiler/intermediate.h
@@ -330,7 +330,7 @@
TString getCompleteString() const { return type.getCompleteString(); }
int totalRegisterCount() const { return type.totalRegisterCount(); }
- int blockRegisterCount() const { return type.blockRegisterCount(); }
+ int blockRegisterCount(bool samplersOnly) const { return samplersOnly ? type.totalSamplerRegisterCount() : type.blockRegisterCount(); }
int elementRegisterCount() const { return type.elementRegisterCount(); }
int registerSize() const { return type.registerSize(); }
int getArraySize() const { return type.getArraySize(); }
diff --git a/src/OpenGL/compiler/osinclude.h b/src/OpenGL/compiler/osinclude.h
index 650f871..54d4c75 100644
--- a/src/OpenGL/compiler/osinclude.h
+++ b/src/OpenGL/compiler/osinclude.h
@@ -26,7 +26,7 @@
defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__sun) || defined(ANDROID) || \
defined(__GLIBC__) || defined(__GNU__) || \
- defined(__QNX__)
+ defined(__QNX__) || defined(__Fuchsia__)
#define ANGLE_OS_POSIX
#else
#error Unsupported platform.
diff --git a/src/OpenGL/compiler/preprocessor/BUILD.gn b/src/OpenGL/compiler/preprocessor/BUILD.gn
index 7c8c2e4..e947c31 100644
--- a/src/OpenGL/compiler/preprocessor/BUILD.gn
+++ b/src/OpenGL/compiler/preprocessor/BUILD.gn
@@ -27,8 +27,8 @@
swiftshader_source_set("swiftshader_opengl_preprocessor") {
sources = [
- "Diagnostics.cpp",
- "DirectiveHandler.cpp",
+ "DiagnosticsBase.cpp",
+ "DirectiveHandlerBase.cpp",
"DirectiveParser.cpp",
"ExpressionParser.cpp",
"Input.cpp",
diff --git a/src/OpenGL/compiler/preprocessor/Diagnostics.cpp b/src/OpenGL/compiler/preprocessor/Diagnostics.cpp
deleted file mode 100644
index 767edd9..0000000
--- a/src/OpenGL/compiler/preprocessor/Diagnostics.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "Diagnostics.h"
-
-#include <cassert>
-
-namespace pp
-{
-
-Diagnostics::~Diagnostics()
-{
-}
-
-void Diagnostics::report(ID id,
- const SourceLocation& loc,
- const std::string& text)
-{
- // TODO(alokp): Keep a count of errors and warnings.
- print(id, loc, text);
-}
-
-Diagnostics::Severity Diagnostics::severity(ID id)
-{
- if ((id > ERROR_BEGIN) && (id < ERROR_END))
- return PP_ERROR;
-
- if ((id > WARNING_BEGIN) && (id < WARNING_END))
- return PP_WARNING;
-
- assert(false);
- return PP_ERROR;
-}
-
-std::string Diagnostics::message(ID id)
-{
- switch (id)
- {
- // Errors begin.
- case INTERNAL_ERROR:
- return "internal error";
- case OUT_OF_MEMORY:
- return "out of memory";
- case INVALID_CHARACTER:
- return "invalid character";
- case INVALID_NUMBER:
- return "invalid number";
- case INTEGER_OVERFLOW:
- return "integer overflow";
- case FLOAT_OVERFLOW:
- return "float overflow";
- case TOKEN_TOO_LONG:
- return "token too long";
- case INVALID_EXPRESSION:
- return "invalid expression";
- case DIVISION_BY_ZERO:
- return "division by zero";
- case EOF_IN_COMMENT:
- return "unexpected end of file found in comment";
- case UNEXPECTED_TOKEN:
- return "unexpected token";
- case DIRECTIVE_INVALID_NAME:
- return "invalid directive name";
- case MACRO_NAME_RESERVED:
- return "macro name is reserved";
- case MACRO_REDEFINED:
- return "macro redefined";
- case MACRO_PREDEFINED_REDEFINED:
- return "predefined macro redefined";
- case MACRO_PREDEFINED_UNDEFINED:
- return "predefined macro undefined";
- case MACRO_UNTERMINATED_INVOCATION:
- return "unterminated macro invocation";
- case MACRO_TOO_FEW_ARGS:
- return "Not enough arguments for macro";
- case MACRO_TOO_MANY_ARGS:
- return "Too many arguments for macro";
- case MACRO_DUPLICATE_PARAMETER_NAMES:
- return "duplicate macro parameter name";
- case CONDITIONAL_ENDIF_WITHOUT_IF:
- return "unexpected #endif found without a matching #if";
- case CONDITIONAL_ELSE_WITHOUT_IF:
- return "unexpected #else found without a matching #if";
- case CONDITIONAL_ELSE_AFTER_ELSE:
- return "unexpected #else found after another #else";
- case CONDITIONAL_ELIF_WITHOUT_IF:
- return "unexpected #elif found without a matching #if";
- case CONDITIONAL_ELIF_AFTER_ELSE:
- return "unexpected #elif found after #else";
- case CONDITIONAL_UNTERMINATED:
- return "unexpected end of file found in conditional block";
- case INVALID_EXTENSION_NAME:
- return "invalid extension name";
- case INVALID_EXTENSION_BEHAVIOR:
- return "invalid extension behavior";
- case INVALID_EXTENSION_DIRECTIVE:
- return "invalid extension directive";
- case INVALID_VERSION_NUMBER:
- return "invalid version number";
- case INVALID_VERSION_DIRECTIVE:
- return "invalid version directive";
- case VERSION_NOT_FIRST_STATEMENT:
- return "#version directive must occur before anything else, "
- "except for comments and white space";
- case INVALID_LINE_NUMBER:
- return "invalid line number";
- case INVALID_FILE_NUMBER:
- return "invalid file number";
- case INVALID_LINE_DIRECTIVE:
- return "invalid line directive";
- case UNDEFINED_IDENTIFIER:
- return "undefined identifier";
- // Errors end.
- // Warnings begin.
- case EOF_IN_DIRECTIVE:
- return "unexpected end of file found in directive";
- case CONDITIONAL_UNEXPECTED_TOKEN:
- return "unexpected token after conditional expression";
- case UNRECOGNIZED_PRAGMA:
- return "unrecognized pragma";
- // Warnings end.
- default:
- assert(false);
- return "";
- }
-}
-
-} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/Diagnostics.h b/src/OpenGL/compiler/preprocessor/Diagnostics.h
deleted file mode 100644
index 1f4cfc4..0000000
--- a/src/OpenGL/compiler/preprocessor/Diagnostics.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
-#define COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
-
-#include <string>
-
-namespace pp
-{
-
-struct SourceLocation;
-
-// Base class for reporting diagnostic messages.
-// Derived classes are responsible for formatting and printing the messages.
-class Diagnostics
-{
-public:
- enum Severity
- {
- PP_ERROR,
- PP_WARNING
- };
- enum ID
- {
- ERROR_BEGIN,
- INTERNAL_ERROR,
- OUT_OF_MEMORY,
- INVALID_CHARACTER,
- INVALID_NUMBER,
- INTEGER_OVERFLOW,
- FLOAT_OVERFLOW,
- TOKEN_TOO_LONG,
- INVALID_EXPRESSION,
- DIVISION_BY_ZERO,
- EOF_IN_COMMENT,
- UNEXPECTED_TOKEN,
- DIRECTIVE_INVALID_NAME,
- MACRO_NAME_RESERVED,
- MACRO_REDEFINED,
- MACRO_PREDEFINED_REDEFINED,
- MACRO_PREDEFINED_UNDEFINED,
- MACRO_UNTERMINATED_INVOCATION,
- MACRO_TOO_FEW_ARGS,
- MACRO_TOO_MANY_ARGS,
- MACRO_DUPLICATE_PARAMETER_NAMES,
- CONDITIONAL_ENDIF_WITHOUT_IF,
- CONDITIONAL_ELSE_WITHOUT_IF,
- CONDITIONAL_ELSE_AFTER_ELSE,
- CONDITIONAL_ELIF_WITHOUT_IF,
- CONDITIONAL_ELIF_AFTER_ELSE,
- CONDITIONAL_UNTERMINATED,
- CONDITIONAL_UNEXPECTED_TOKEN,
- INVALID_EXTENSION_NAME,
- INVALID_EXTENSION_BEHAVIOR,
- INVALID_EXTENSION_DIRECTIVE,
- INVALID_VERSION_NUMBER,
- INVALID_VERSION_DIRECTIVE,
- VERSION_NOT_FIRST_STATEMENT,
- INVALID_LINE_NUMBER,
- INVALID_FILE_NUMBER,
- INVALID_LINE_DIRECTIVE,
- UNDEFINED_IDENTIFIER,
- ERROR_END,
-
- WARNING_BEGIN,
- EOF_IN_DIRECTIVE,
- UNRECOGNIZED_PRAGMA,
- WARNING_END
- };
-
- virtual ~Diagnostics();
-
- void report(ID id, const SourceLocation& loc, const std::string& text);
-
-protected:
- Severity severity(ID id);
- std::string message(ID id);
-
- virtual void print(ID id,
- const SourceLocation& loc,
- const std::string& text) = 0;
-};
-
-} // namespace pp
-#endif // COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
diff --git a/src/OpenGL/compiler/preprocessor/DiagnosticsBase.cpp b/src/OpenGL/compiler/preprocessor/DiagnosticsBase.cpp
new file mode 100644
index 0000000..0cea776
--- /dev/null
+++ b/src/OpenGL/compiler/preprocessor/DiagnosticsBase.cpp
@@ -0,0 +1,163 @@
+// Copyright 2017 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "DiagnosticsBase.h"
+
+#include <cassert>
+
+namespace pp
+{
+
+Diagnostics::~Diagnostics()
+{
+}
+
+void Diagnostics::report(ID id, const SourceLocation &loc, const std::string &text)
+{
+ print(id, loc, text);
+}
+
+bool Diagnostics::isError(ID id)
+{
+ if ((id > PP_ERROR_BEGIN) && (id < PP_ERROR_END))
+ return true;
+
+ if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END))
+ return false;
+
+ assert(false);
+ return true;
+}
+
+Diagnostics::Severity Diagnostics::severity(ID id)
+{
+ if((id > PP_ERROR_BEGIN) && (id < PP_ERROR_END))
+ return PP_ERROR;
+
+ if((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END))
+ return PP_WARNING;
+
+ assert(false);
+ return PP_ERROR;
+}
+
+const char *Diagnostics::message(ID id)
+{
+ switch (id)
+ {
+ // Errors begin.
+ case PP_INTERNAL_ERROR:
+ return "internal error";
+ case PP_OUT_OF_MEMORY:
+ return "out of memory";
+ case PP_INVALID_CHARACTER:
+ return "invalid character";
+ case PP_INVALID_NUMBER:
+ return "invalid number";
+ case PP_INTEGER_OVERFLOW:
+ return "integer overflow";
+ case PP_FLOAT_OVERFLOW:
+ return "float overflow";
+ case PP_TOKEN_TOO_LONG:
+ return "token too long";
+ case PP_INVALID_EXPRESSION:
+ return "invalid expression";
+ case PP_DIVISION_BY_ZERO:
+ return "division by zero";
+ case PP_EOF_IN_COMMENT:
+ return "unexpected end of file found in comment";
+ case PP_UNEXPECTED_TOKEN:
+ return "unexpected token";
+ case PP_DIRECTIVE_INVALID_NAME:
+ return "invalid directive name";
+ case PP_MACRO_NAME_RESERVED:
+ return "macro name is reserved";
+ case PP_MACRO_REDEFINED:
+ return "macro redefined";
+ case PP_MACRO_PREDEFINED_REDEFINED:
+ return "predefined macro redefined";
+ case PP_MACRO_PREDEFINED_UNDEFINED:
+ return "predefined macro undefined";
+ case PP_MACRO_UNTERMINATED_INVOCATION:
+ return "unterminated macro invocation";
+ case PP_MACRO_UNDEFINED_WHILE_INVOKED:
+ return "macro undefined while being invoked";
+ case PP_MACRO_TOO_FEW_ARGS:
+ return "Not enough arguments for macro";
+ case PP_MACRO_TOO_MANY_ARGS:
+ return "Too many arguments for macro";
+ case PP_MACRO_DUPLICATE_PARAMETER_NAMES:
+ return "duplicate macro parameter name";
+ case PP_MACRO_INVOCATION_CHAIN_TOO_DEEP:
+ return "macro invocation chain too deep";
+ case PP_CONDITIONAL_ENDIF_WITHOUT_IF:
+ return "unexpected #endif found without a matching #if";
+ case PP_CONDITIONAL_ELSE_WITHOUT_IF:
+ return "unexpected #else found without a matching #if";
+ case PP_CONDITIONAL_ELSE_AFTER_ELSE:
+ return "unexpected #else found after another #else";
+ case PP_CONDITIONAL_ELIF_WITHOUT_IF:
+ return "unexpected #elif found without a matching #if";
+ case PP_CONDITIONAL_ELIF_AFTER_ELSE:
+ return "unexpected #elif found after #else";
+ case PP_CONDITIONAL_UNTERMINATED:
+ return "unexpected end of file found in conditional block";
+ case PP_INVALID_EXTENSION_NAME:
+ return "invalid extension name";
+ case PP_INVALID_EXTENSION_BEHAVIOR:
+ return "invalid extension behavior";
+ case PP_INVALID_EXTENSION_DIRECTIVE:
+ return "invalid extension directive";
+ case PP_INVALID_VERSION_NUMBER:
+ return "invalid version number";
+ case PP_INVALID_VERSION_DIRECTIVE:
+ return "invalid version directive";
+ case PP_VERSION_NOT_FIRST_STATEMENT:
+ return "#version directive must occur before anything else, "
+ "except for comments and white space";
+ case PP_VERSION_NOT_FIRST_LINE_ESSL3:
+ return "#version directive must occur on the first line of the shader";
+ case PP_INVALID_LINE_NUMBER:
+ return "invalid line number";
+ case PP_INVALID_FILE_NUMBER:
+ return "invalid file number";
+ case PP_INVALID_LINE_DIRECTIVE:
+ return "invalid line directive";
+ case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3:
+ return "extension directive must occur before any non-preprocessor tokens in ESSL3";
+ case PP_UNDEFINED_SHIFT:
+ return "shift exponent is negative or undefined";
+ case PP_TOKENIZER_ERROR:
+ return "internal tokenizer error";
+ // Errors end.
+ // Warnings begin.
+ case PP_EOF_IN_DIRECTIVE:
+ return "unexpected end of file found in directive";
+ case PP_CONDITIONAL_UNEXPECTED_TOKEN:
+ return "unexpected token after conditional expression";
+ case PP_UNRECOGNIZED_PRAGMA:
+ return "unrecognized pragma";
+ case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1:
+ return "extension directive should occur before any non-preprocessor tokens";
+ case PP_WARNING_MACRO_NAME_RESERVED:
+ return "macro name with a double underscore is reserved - unintented behavior is "
+ "possible";
+ // Warnings end.
+ default:
+ assert(false);
+ return "";
+ }
+}
+
+} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/DiagnosticsBase.h b/src/OpenGL/compiler/preprocessor/DiagnosticsBase.h
new file mode 100644
index 0000000..16e6881
--- /dev/null
+++ b/src/OpenGL/compiler/preprocessor/DiagnosticsBase.h
@@ -0,0 +1,106 @@
+// Copyright 2017 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
+#define COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
+
+#include <string>
+
+namespace pp
+{
+
+struct SourceLocation;
+
+// Base class for reporting diagnostic messages.
+// Derived classes are responsible for formatting and printing the messages.
+class Diagnostics
+{
+public:
+ // Severity is used to classify info log messages.
+ enum Severity
+ {
+ PP_WARNING,
+ PP_ERROR
+ };
+
+ enum ID
+ {
+ PP_ERROR_BEGIN,
+ PP_INTERNAL_ERROR,
+ PP_OUT_OF_MEMORY,
+ PP_INVALID_CHARACTER,
+ PP_INVALID_NUMBER,
+ PP_INTEGER_OVERFLOW,
+ PP_FLOAT_OVERFLOW,
+ PP_TOKEN_TOO_LONG,
+ PP_INVALID_EXPRESSION,
+ PP_DIVISION_BY_ZERO,
+ PP_EOF_IN_COMMENT,
+ PP_UNEXPECTED_TOKEN,
+ PP_DIRECTIVE_INVALID_NAME,
+ PP_MACRO_NAME_RESERVED,
+ PP_MACRO_REDEFINED,
+ PP_MACRO_PREDEFINED_REDEFINED,
+ PP_MACRO_PREDEFINED_UNDEFINED,
+ PP_MACRO_UNTERMINATED_INVOCATION,
+ PP_MACRO_UNDEFINED_WHILE_INVOKED,
+ PP_MACRO_TOO_FEW_ARGS,
+ PP_MACRO_TOO_MANY_ARGS,
+ PP_MACRO_DUPLICATE_PARAMETER_NAMES,
+ PP_MACRO_INVOCATION_CHAIN_TOO_DEEP,
+ PP_CONDITIONAL_ENDIF_WITHOUT_IF,
+ PP_CONDITIONAL_ELSE_WITHOUT_IF,
+ PP_CONDITIONAL_ELSE_AFTER_ELSE,
+ PP_CONDITIONAL_ELIF_WITHOUT_IF,
+ PP_CONDITIONAL_ELIF_AFTER_ELSE,
+ PP_CONDITIONAL_UNTERMINATED,
+ PP_CONDITIONAL_UNEXPECTED_TOKEN,
+ PP_INVALID_EXTENSION_NAME,
+ PP_INVALID_EXTENSION_BEHAVIOR,
+ PP_INVALID_EXTENSION_DIRECTIVE,
+ PP_INVALID_VERSION_NUMBER,
+ PP_INVALID_VERSION_DIRECTIVE,
+ PP_VERSION_NOT_FIRST_STATEMENT,
+ PP_VERSION_NOT_FIRST_LINE_ESSL3,
+ PP_INVALID_LINE_NUMBER,
+ PP_INVALID_FILE_NUMBER,
+ PP_INVALID_LINE_DIRECTIVE,
+ PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3,
+ PP_UNDEFINED_SHIFT,
+ PP_TOKENIZER_ERROR,
+ PP_ERROR_END,
+
+ PP_WARNING_BEGIN,
+ PP_EOF_IN_DIRECTIVE,
+ PP_UNRECOGNIZED_PRAGMA,
+ PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
+ PP_WARNING_MACRO_NAME_RESERVED,
+ PP_WARNING_END
+ };
+
+ virtual ~Diagnostics();
+
+ void report(ID id, const SourceLocation &loc, const std::string &text);
+
+protected:
+ bool isError(ID id);
+ const char *message(ID id);
+ Severity severity(ID id);
+
+ virtual void print(ID id, const SourceLocation &loc, const std::string &text) = 0;
+};
+
+} // namespace pp
+
+#endif // COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveHandler.h b/src/OpenGL/compiler/preprocessor/DirectiveHandler.h
deleted file mode 100644
index f7b3784..0000000
--- a/src/OpenGL/compiler/preprocessor/DirectiveHandler.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
-#define COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
-
-#include <string>
-
-namespace pp
-{
-
-struct SourceLocation;
-
-// Base class for handling directives.
-// Preprocessor uses this class to notify the clients about certain
-// preprocessor directives. Derived classes are responsible for
-// handling them in an appropriate manner.
-class DirectiveHandler
-{
-public:
- virtual ~DirectiveHandler();
-
- virtual void handleError(const SourceLocation& loc,
- const std::string& msg) = 0;
-
- // Handle pragma of form: #pragma name[(value)]
- virtual void handlePragma(const SourceLocation& loc,
- const std::string& name,
- const std::string& value) = 0;
-
- virtual void handleExtension(const SourceLocation& loc,
- const std::string& name,
- const std::string& behavior) = 0;
-
- virtual void handleVersion(const SourceLocation& loc,
- int version) = 0;
-};
-
-} // namespace pp
-#endif // COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveHandler.cpp b/src/OpenGL/compiler/preprocessor/DirectiveHandlerBase.cpp
similarity index 86%
rename from src/OpenGL/compiler/preprocessor/DirectiveHandler.cpp
rename to src/OpenGL/compiler/preprocessor/DirectiveHandlerBase.cpp
index ac26c83..e1f1015 100644
--- a/src/OpenGL/compiler/preprocessor/DirectiveHandler.cpp
+++ b/src/OpenGL/compiler/preprocessor/DirectiveHandlerBase.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+// Copyright 2017 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "DirectiveHandler.h"
+#include "DirectiveHandlerBase.h"
namespace pp
{
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveHandlerBase.h b/src/OpenGL/compiler/preprocessor/DirectiveHandlerBase.h
new file mode 100644
index 0000000..54ddc9d
--- /dev/null
+++ b/src/OpenGL/compiler/preprocessor/DirectiveHandlerBase.h
@@ -0,0 +1,51 @@
+// Copyright 2017 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
+#define COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
+
+#include <string>
+
+namespace pp
+{
+
+struct SourceLocation;
+
+// Base class for handling directives.
+// Preprocessor uses this class to notify the clients about certain
+// preprocessor directives. Derived classes are responsible for
+// handling them in an appropriate manner.
+class DirectiveHandler
+{
+ public:
+ virtual ~DirectiveHandler();
+
+ virtual void handleError(const SourceLocation &loc, const std::string &msg) = 0;
+
+ // Handle pragma of form: #pragma name[(value)]
+ virtual void handlePragma(const SourceLocation &loc,
+ const std::string &name,
+ const std::string &value,
+ bool stdgl) = 0;
+
+ virtual void handleExtension(const SourceLocation &loc,
+ const std::string &name,
+ const std::string &behavior) = 0;
+
+ virtual void handleVersion(const SourceLocation &loc, int version) = 0;
+};
+
+} // namespace pp
+
+#endif // COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp b/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
index ec77c21..9eb044e 100644
--- a/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
+++ b/src/OpenGL/compiler/preprocessor/DirectiveParser.cpp
@@ -14,12 +14,13 @@
#include "DirectiveParser.h"
+#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <sstream>
-#include "Diagnostics.h"
-#include "DirectiveHandler.h"
+#include "DiagnosticsBase.h"
+#include "DirectiveHandlerBase.h"
#include "ExpressionParser.h"
#include "MacroExpander.h"
#include "Token.h"
@@ -45,7 +46,7 @@
};
} // namespace
-static DirectiveType getDirective(const pp::Token* token)
+static DirectiveType getDirective(const pp::Token *token)
{
static const std::string kDirectiveDefine("define");
static const std::string kDirectiveUndef("undef");
@@ -111,12 +112,12 @@
}
// Returns true if the token represents End Of Directive.
-static bool isEOD(const pp::Token* token)
+static bool isEOD(const pp::Token *token)
{
return (token->type == '\n') || (token->type == pp::Token::LAST);
}
-static void skipUntilEOD(pp::Lexer* lexer, pp::Token* token)
+static void skipUntilEOD(pp::Lexer *lexer, pp::Token *token)
{
while(!isEOD(token))
{
@@ -127,39 +128,105 @@
static bool isMacroNameReserved(const std::string& name)
{
// Names prefixed with "GL_" are reserved.
- if (name.substr(0, 3) == "GL_")
- return true;
+ return (name.substr(0, 3) == "GL_");
+}
- // Names containing two consecutive underscores are reserved.
- if (name.find("__") != std::string::npos)
- return true;
-
- return false;
+bool hasDoubleUnderscores(const std::string &name)
+{
+ return (name.find("__") != std::string::npos);
}
static bool isMacroPredefined(const std::string& name,
const pp::MacroSet& macroSet)
{
pp::MacroSet::const_iterator iter = macroSet.find(name);
- return iter != macroSet.end() ? iter->second.predefined : false;
+ return iter != macroSet.end() ? iter->second->predefined : false;
}
namespace pp
{
-DirectiveParser::DirectiveParser(Tokenizer* tokenizer,
- MacroSet* macroSet,
- Diagnostics* diagnostics,
- DirectiveHandler* directiveHandler) :
- mPastFirstStatement(false),
- mTokenizer(tokenizer),
- mMacroSet(macroSet),
- mDiagnostics(diagnostics),
- mDirectiveHandler(directiveHandler)
+class DefinedParser : public Lexer
+{
+public:
+ DefinedParser(Lexer *lexer, const MacroSet *macroSet, Diagnostics *diagnostics)
+ : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics)
+ {
+ }
+
+protected:
+ void lex(Token *token) override
+ {
+ const char kDefined[] = "defined";
+
+ mLexer->lex(token);
+ if (token->type != Token::IDENTIFIER)
+ return;
+ if (token->text != kDefined)
+ return;
+
+ bool paren = false;
+ mLexer->lex(token);
+ if (token->type == '(')
+ {
+ paren = true;
+ mLexer->lex(token);
+ }
+
+ if (token->type != Token::IDENTIFIER)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
+ skipUntilEOD(mLexer, token);
+ return;
+ }
+ MacroSet::const_iterator iter = mMacroSet->find(token->text);
+ std::string expression = iter != mMacroSet->end() ? "1" : "0";
+
+ if (paren)
+ {
+ mLexer->lex(token);
+ if (token->type != ')')
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
+ token->location, token->text);
+ skipUntilEOD(mLexer, token);
+ return;
+ }
+ }
+
+ // We have a valid defined operator.
+ // Convert the current token into a CONST_INT token.
+ token->type = Token::CONST_INT;
+ token->text = expression;
+ }
+
+private:
+ Lexer *mLexer;
+ const MacroSet *mMacroSet;
+ Diagnostics *mDiagnostics;
+};
+
+DirectiveParser::DirectiveParser(Tokenizer *tokenizer,
+ MacroSet *macroSet,
+ Diagnostics *diagnostics,
+ DirectiveHandler *directiveHandler,
+ int maxMacroExpansionDepth)
+ : mPastFirstStatement(false),
+ mSeenNonPreprocessorToken(false),
+ mTokenizer(tokenizer),
+ mMacroSet(macroSet),
+ mDiagnostics(diagnostics),
+ mDirectiveHandler(directiveHandler),
+ mShaderVersion(100),
+ mMaxMacroExpansionDepth(maxMacroExpansionDepth)
{
}
-void DirectiveParser::lex(Token* token)
+DirectiveParser::~DirectiveParser()
+{
+}
+
+void DirectiveParser::lex(Token *token)
{
do
{
@@ -170,13 +237,17 @@
parseDirective(token);
mPastFirstStatement = true;
}
+ else if (!isEOD(token))
+ {
+ mSeenNonPreprocessorToken = true;
+ }
if (token->type == Token::LAST)
{
if (!mConditionalStack.empty())
{
- const ConditionalBlock& block = mConditionalStack.back();
- mDiagnostics->report(Diagnostics::CONDITIONAL_UNTERMINATED,
+ const ConditionalBlock &block = mConditionalStack.back();
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED,
block.location, block.type);
}
break;
@@ -187,7 +258,7 @@
mPastFirstStatement = true;
}
-void DirectiveParser::parseDirective(Token* token)
+void DirectiveParser::parseDirective(Token *token)
{
assert(token->type == Token::PP_HASH);
@@ -211,7 +282,7 @@
switch(directive)
{
case DIRECTIVE_NONE:
- mDiagnostics->report(Diagnostics::DIRECTIVE_INVALID_NAME,
+ mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
break;
@@ -262,64 +333,74 @@
skipUntilEOD(mTokenizer, token);
if (token->type == Token::LAST)
{
- mDiagnostics->report(Diagnostics::EOF_IN_DIRECTIVE,
+ mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE,
token->location, token->text);
}
}
-void DirectiveParser::parseDefine(Token* token)
+void DirectiveParser::parseDefine(Token *token)
{
assert(getDirective(token) == DIRECTIVE_DEFINE);
mTokenizer->lex(token);
if (token->type != Token::IDENTIFIER)
{
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
token->location, token->text);
return;
}
if (isMacroPredefined(token->text, *mMacroSet))
{
- mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_REDEFINED,
+ mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED,
token->location, token->text);
return;
}
if (isMacroNameReserved(token->text))
{
- mDiagnostics->report(Diagnostics::MACRO_NAME_RESERVED,
+ mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED,
token->location, token->text);
return;
}
+ // Using double underscores is allowed, but may result in unintended
+ // behavior, so a warning is issued. At the time of writing this was
+ // specified in ESSL 3.10, but the intent judging from Khronos
+ // discussions and dEQP tests was that double underscores should be
+ // allowed in earlier ESSL versions too.
+ if (hasDoubleUnderscores(token->text))
+ {
+ mDiagnostics->report(Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, token->location,
+ token->text);
+ }
- Macro macro;
- macro.type = Macro::kTypeObj;
- macro.name = token->text;
+ std::shared_ptr<Macro> macro = std::make_shared<Macro>();
+ macro->type = Macro::kTypeObj;
+ macro->name = token->text;
mTokenizer->lex(token);
if (token->type == '(' && !token->hasLeadingSpace())
{
// Function-like macro. Collect arguments.
- macro.type = Macro::kTypeFunc;
+ macro->type = Macro::kTypeFunc;
do {
mTokenizer->lex(token);
if (token->type != Token::IDENTIFIER)
break;
- if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end())
+ if (std::find(macro->parameters.begin(), macro->parameters.end(), token->text) != macro->parameters.end())
{
- mDiagnostics->report(Diagnostics::MACRO_DUPLICATE_PARAMETER_NAMES,
+ mDiagnostics->report(Diagnostics::PP_MACRO_DUPLICATE_PARAMETER_NAMES,
token->location, token->text);
return;
}
- macro.parameters.push_back(token->text);
+ macro->parameters.push_back(token->text);
mTokenizer->lex(token); // Get ','.
} while (token->type == ',');
if (token->type != ')')
{
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
token->location,
token->text);
return;
@@ -333,36 +414,34 @@
// list. Resetting it also allows us to reuse Token::equals() to
// compare macros.
token->location = SourceLocation();
- macro.replacements.push_back(*token);
+ macro->replacements.push_back(*token);
mTokenizer->lex(token);
}
- if (!macro.replacements.empty())
+ if (!macro->replacements.empty())
{
// Whitespace preceding the replacement list is not considered part of
// the replacement list for either form of macro.
- macro.replacements.front().setHasLeadingSpace(false);
+ macro->replacements.front().setHasLeadingSpace(false);
}
// Check for macro redefinition.
- MacroSet::const_iterator iter = mMacroSet->find(macro.name);
- if (iter != mMacroSet->end() && !macro.equals(iter->second))
+ MacroSet::const_iterator iter = mMacroSet->find(macro->name);
+ if (iter != mMacroSet->end() && !macro->equals(*iter->second))
{
- mDiagnostics->report(Diagnostics::MACRO_REDEFINED,
- token->location,
- macro.name);
+ mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro->name);
return;
}
- mMacroSet->insert(std::make_pair(macro.name, macro));
+ mMacroSet->insert(std::make_pair(macro->name, macro));
}
-void DirectiveParser::parseUndef(Token* token)
+void DirectiveParser::parseUndef(Token *token)
{
assert(getDirective(token) == DIRECTIVE_UNDEF);
mTokenizer->lex(token);
if (token->type != Token::IDENTIFIER)
{
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
token->location, token->text);
return;
}
@@ -370,10 +449,17 @@
MacroSet::iterator iter = mMacroSet->find(token->text);
if (iter != mMacroSet->end())
{
- if (iter->second.predefined)
+ if (iter->second->predefined)
{
- mDiagnostics->report(Diagnostics::MACRO_PREDEFINED_UNDEFINED,
+ mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED,
token->location, token->text);
+ return;
+ }
+ else if (iter->second->expansionCount > 0)
+ {
+ mDiagnostics->report(Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED,
+ token->location, token->text);
+ return;
}
else
{
@@ -382,39 +468,44 @@
}
mTokenizer->lex(token);
+ if (!isEOD(token))
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
+ skipUntilEOD(mTokenizer, token);
+ }
}
-void DirectiveParser::parseIf(Token* token)
+void DirectiveParser::parseIf(Token *token)
{
assert(getDirective(token) == DIRECTIVE_IF);
parseConditionalIf(token);
}
-void DirectiveParser::parseIfdef(Token* token)
+void DirectiveParser::parseIfdef(Token *token)
{
assert(getDirective(token) == DIRECTIVE_IFDEF);
parseConditionalIf(token);
}
-void DirectiveParser::parseIfndef(Token* token)
+void DirectiveParser::parseIfndef(Token *token)
{
assert(getDirective(token) == DIRECTIVE_IFNDEF);
parseConditionalIf(token);
}
-void DirectiveParser::parseElse(Token* token)
+void DirectiveParser::parseElse(Token *token)
{
assert(getDirective(token) == DIRECTIVE_ELSE);
if (mConditionalStack.empty())
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_WITHOUT_IF,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
return;
}
- ConditionalBlock& block = mConditionalStack.back();
+ ConditionalBlock &block = mConditionalStack.back();
if (block.skipBlock)
{
// No diagnostics. Just skip the whole line.
@@ -423,7 +514,7 @@
}
if (block.foundElseGroup)
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_ELSE_AFTER_ELSE,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
return;
@@ -437,25 +528,25 @@
mTokenizer->lex(token);
if (!isEOD(token))
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
}
}
-void DirectiveParser::parseElif(Token* token)
+void DirectiveParser::parseElif(Token *token)
{
assert(getDirective(token) == DIRECTIVE_ELIF);
if (mConditionalStack.empty())
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_WITHOUT_IF,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
return;
}
- ConditionalBlock& block = mConditionalStack.back();
+ ConditionalBlock &block = mConditionalStack.back();
if (block.skipBlock)
{
// No diagnostics. Just skip the whole line.
@@ -464,7 +555,7 @@
}
if (block.foundElseGroup)
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_ELIF_AFTER_ELSE,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
return;
@@ -483,13 +574,13 @@
block.foundValidGroup = expression != 0;
}
-void DirectiveParser::parseEndif(Token* token)
+void DirectiveParser::parseEndif(Token *token)
{
assert(getDirective(token) == DIRECTIVE_ENDIF);
if (mConditionalStack.empty())
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_ENDIF_WITHOUT_IF,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
return;
@@ -501,13 +592,13 @@
mTokenizer->lex(token);
if (!isEOD(token))
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
}
}
-void DirectiveParser::parseError(Token* token)
+void DirectiveParser::parseError(Token *token)
{
assert(getDirective(token) == DIRECTIVE_ERROR);
@@ -522,7 +613,7 @@
}
// Parses pragma of form: #pragma name[(value)].
-void DirectiveParser::parsePragma(Token* token)
+void DirectiveParser::parsePragma(Token *token)
{
assert(getDirective(token) == DIRECTIVE_PRAGMA);
@@ -539,6 +630,11 @@
int state = PRAGMA_NAME;
mTokenizer->lex(token);
+ bool stdgl = token->text == "STDGL";
+ if (stdgl)
+ {
+ mTokenizer->lex(token);
+ }
while ((token->type != '\n') && (token->type != Token::LAST))
{
switch(state++)
@@ -569,16 +665,15 @@
(state == RIGHT_PAREN + 1)); // With value.
if (!valid)
{
- mDiagnostics->report(Diagnostics::UNRECOGNIZED_PRAGMA,
- token->location, name);
+ mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, token->location, name);
}
else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
{
- mDirectiveHandler->handlePragma(token->location, name, value);
+ mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
}
}
-void DirectiveParser::parseExtension(Token* token)
+void DirectiveParser::parseExtension(Token *token)
{
assert(getDirective(token) == DIRECTIVE_EXTENSION);
@@ -598,61 +693,77 @@
{
switch (state++)
{
- case EXT_NAME:
- if (valid && (token->type != Token::IDENTIFIER))
- {
- mDiagnostics->report(Diagnostics::INVALID_EXTENSION_NAME,
- token->location, token->text);
- valid = false;
- }
- if (valid) name = token->text;
- break;
- case COLON:
- if (valid && (token->type != ':'))
- {
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
- token->location, token->text);
- valid = false;
- }
- break;
- case EXT_BEHAVIOR:
- if (valid && (token->type != Token::IDENTIFIER))
- {
- mDiagnostics->report(Diagnostics::INVALID_EXTENSION_BEHAVIOR,
- token->location, token->text);
- valid = false;
- }
- if (valid) behavior = token->text;
- break;
- default:
- if (valid)
- {
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
- token->location, token->text);
- valid = false;
- }
- break;
+ case EXT_NAME:
+ if (valid && (token->type != Token::IDENTIFIER))
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, token->location,
+ token->text);
+ valid = false;
+ }
+ if (valid)
+ name = token->text;
+ break;
+ case COLON:
+ if (valid && (token->type != ':'))
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ valid = false;
+ }
+ break;
+ case EXT_BEHAVIOR:
+ if (valid && (token->type != Token::IDENTIFIER))
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR,
+ token->location, token->text);
+ valid = false;
+ }
+ if (valid)
+ behavior = token->text;
+ break;
+ default:
+ if (valid)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ valid = false;
+ }
+ break;
}
mTokenizer->lex(token);
}
if (valid && (state != EXT_BEHAVIOR + 1))
{
- mDiagnostics->report(Diagnostics::INVALID_EXTENSION_DIRECTIVE,
- token->location, token->text);
+ mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, token->location,
+ token->text);
valid = false;
}
+ if (valid && mSeenNonPreprocessorToken)
+ {
+ if (mShaderVersion >= 300)
+ {
+ mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3,
+ token->location, token->text);
+ valid = false;
+ }
+ else
+ {
+ mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
+ token->location, token->text);
+ }
+ }
if (valid)
mDirectiveHandler->handleExtension(token->location, name, behavior);
}
-void DirectiveParser::parseVersion(Token* token)
+void DirectiveParser::parseVersion(Token *token)
{
assert(getDirective(token) == DIRECTIVE_VERSION);
if (mPastFirstStatement)
{
- mDiagnostics->report(Diagnostics::VERSION_NOT_FIRST_STATEMENT,
- token->location, token->text);
+ mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, token->location,
+ token->text);
skipUntilEOD(mTokenizer, token);
return;
}
@@ -676,13 +787,13 @@
case VERSION_NUMBER:
if (token->type != Token::CONST_INT)
{
- mDiagnostics->report(Diagnostics::INVALID_VERSION_NUMBER,
+ mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER,
token->location, token->text);
valid = false;
}
if (valid && !token->iValue(&version))
{
- mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
+ mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW,
token->location, token->text);
valid = false;
}
@@ -694,14 +805,14 @@
case VERSION_PROFILE:
if (token->type != Token::IDENTIFIER || token->text != "es")
{
- mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,
+ mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE,
token->location, token->text);
valid = false;
}
state = VERSION_ENDLINE;
break;
default:
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
token->location, token->text);
valid = false;
break;
@@ -712,99 +823,98 @@
if (valid && (state != VERSION_ENDLINE))
{
- mDiagnostics->report(Diagnostics::INVALID_VERSION_DIRECTIVE,
+ mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE,
token->location, token->text);
valid = false;
}
+ if (valid && version >= 300 && token->location.line > 1)
+ {
+ mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_LINE_ESSL3, token->location,
+ token->text);
+ valid = false;
+ }
+
if (valid)
{
mDirectiveHandler->handleVersion(token->location, version);
+ mShaderVersion = version;
+ PredefineMacro(mMacroSet, "__VERSION__", version);
}
}
-void DirectiveParser::parseLine(Token* token)
+void DirectiveParser::parseLine(Token *token)
{
assert(getDirective(token) == DIRECTIVE_LINE);
- enum State
- {
- LINE_NUMBER,
- FILE_NUMBER
- };
-
bool valid = true;
+ bool parsedFileNumber = false;
int line = 0, file = 0;
- int state = LINE_NUMBER;
- MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false);
+ MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false, mMaxMacroExpansionDepth);
+
+ // Lex the first token after "#line" so we can check it for EOD.
macroExpander.lex(token);
- while ((token->type != '\n') && (token->type != Token::LAST))
- {
- switch (state++)
- {
- case LINE_NUMBER:
- if (valid && (token->type != Token::CONST_INT))
- {
- mDiagnostics->report(Diagnostics::INVALID_LINE_NUMBER,
- token->location, token->text);
- valid = false;
- }
- if (valid && !token->iValue(&line))
- {
- mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
- token->location, token->text);
- valid = false;
- }
- break;
- case FILE_NUMBER:
- if (valid && (token->type != Token::CONST_INT))
- {
- mDiagnostics->report(Diagnostics::INVALID_FILE_NUMBER,
- token->location, token->text);
- valid = false;
- }
- if (valid && !token->iValue(&file))
- {
- mDiagnostics->report(Diagnostics::INTEGER_OVERFLOW,
- token->location, token->text);
- valid = false;
- }
- break;
- default:
- if (valid)
- {
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
- token->location, token->text);
- valid = false;
- }
- break;
- }
- macroExpander.lex(token);
- }
- if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1))
+ if (isEOD(token))
{
- mDiagnostics->report(Diagnostics::INVALID_LINE_DIRECTIVE,
- token->location, token->text);
+ mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, token->location, token->text);
valid = false;
}
+ else
+ {
+ ExpressionParser expressionParser(¯oExpander, mDiagnostics);
+ ExpressionParser::ErrorSettings errorSettings;
+
+ // See GLES3 section 12.42
+ errorSettings.integerLiteralsMustFit32BitSignedRange = true;
+
+ errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_LINE_NUMBER;
+ // The first token was lexed earlier to check if it was EOD. Include
+ // the token in parsing for a second time by setting the
+ // parsePresetToken flag to true.
+ expressionParser.parse(token, &line, true, errorSettings, &valid);
+ if (!isEOD(token) && valid)
+ {
+ errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_FILE_NUMBER;
+ // After parsing the line expression expressionParser has also
+ // advanced to the first token of the file expression - this is the
+ // token that makes the parser reduce the "input" rule for the line
+ // expression and stop. So we're using parsePresetToken = true here
+ // as well.
+ expressionParser.parse(token, &file, true, errorSettings, &valid);
+ parsedFileNumber = true;
+ }
+ if (!isEOD(token))
+ {
+ if (valid)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
+ token->location, token->text);
+ valid = false;
+ }
+ skipUntilEOD(mTokenizer, token);
+ }
+ }
+
if (valid)
{
mTokenizer->setLineNumber(line);
- if (state == FILE_NUMBER + 1) mTokenizer->setFileNumber(file);
+ if (parsedFileNumber)
+ mTokenizer->setFileNumber(file);
}
}
bool DirectiveParser::skipping() const
{
- if (mConditionalStack.empty()) return false;
+ if (mConditionalStack.empty())
+ return false;
- const ConditionalBlock& block = mConditionalStack.back();
+ const ConditionalBlock &block = mConditionalStack.back();
return block.skipBlock || block.skipGroup;
}
-void DirectiveParser::parseConditionalIf(Token* token)
+void DirectiveParser::parseConditionalIf(Token *token)
{
ConditionalBlock block;
block.type = token->text;
@@ -845,22 +955,26 @@
mConditionalStack.push_back(block);
}
-int DirectiveParser::parseExpressionIf(Token* token)
+int DirectiveParser::parseExpressionIf(Token *token)
{
- assert((getDirective(token) == DIRECTIVE_IF) ||
- (getDirective(token) == DIRECTIVE_ELIF));
+ assert((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF));
- MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true);
+ DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
+ MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics, true, mMaxMacroExpansionDepth);
ExpressionParser expressionParser(¯oExpander, mDiagnostics);
int expression = 0;
- macroExpander.lex(token);
- expressionParser.parse(token, &expression);
+ ExpressionParser::ErrorSettings errorSettings;
+ errorSettings.integerLiteralsMustFit32BitSignedRange = false;
+ errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN;
+
+ bool valid = true;
+ expressionParser.parse(token, &expression, false, errorSettings, &valid);
// Check if there are tokens after #if expression.
if (!isEOD(token))
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
}
@@ -876,7 +990,7 @@
mTokenizer->lex(token);
if (token->type != Token::IDENTIFIER)
{
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
return 0;
@@ -889,7 +1003,7 @@
mTokenizer->lex(token);
if (!isEOD(token))
{
- mDiagnostics->report(Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN,
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
token->location, token->text);
skipUntilEOD(mTokenizer, token);
}
diff --git a/src/OpenGL/compiler/preprocessor/DirectiveParser.h b/src/OpenGL/compiler/preprocessor/DirectiveParser.h
index b23a99e..d1e1135 100644
--- a/src/OpenGL/compiler/preprocessor/DirectiveParser.h
+++ b/src/OpenGL/compiler/preprocessor/DirectiveParser.h
@@ -30,35 +30,37 @@
class DirectiveParser : public Lexer
{
public:
- DirectiveParser(Tokenizer* tokenizer,
- MacroSet* macroSet,
- Diagnostics* diagnostics,
- DirectiveHandler* directiveHandler);
+ DirectiveParser(Tokenizer *tokenizer,
+ MacroSet *macroSet,
+ Diagnostics *diagnostics,
+ DirectiveHandler *directiveHandler,
+ int maxMacroExpansionDepth);
+ ~DirectiveParser() override;
- virtual void lex(Token* token);
+ void lex(Token *token) override;
private:
PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser);
- void parseDirective(Token* token);
- void parseDefine(Token* token);
- void parseUndef(Token* token);
- void parseIf(Token* token);
- void parseIfdef(Token* token);
- void parseIfndef(Token* token);
- void parseElse(Token* token);
- void parseElif(Token* token);
- void parseEndif(Token* token);
- void parseError(Token* token);
- void parsePragma(Token* token);
- void parseExtension(Token* token);
- void parseVersion(Token* token);
- void parseLine(Token* token);
+ void parseDirective(Token *token);
+ void parseDefine(Token *token);
+ void parseUndef(Token *token);
+ void parseIf(Token *token);
+ void parseIfdef(Token *token);
+ void parseIfndef(Token *token);
+ void parseElse(Token *token);
+ void parseElif(Token *token);
+ void parseEndif(Token *token);
+ void parseError(Token *token);
+ void parsePragma(Token *token);
+ void parseExtension(Token *token);
+ void parseVersion(Token *token);
+ void parseLine(Token *token);
bool skipping() const;
- void parseConditionalIf(Token* token);
- int parseExpressionIf(Token* token);
- int parseExpressionIfdef(Token* token);
+ void parseConditionalIf(Token *token);
+ int parseExpressionIf(Token *token);
+ int parseExpressionIfdef(Token *token);
struct ConditionalBlock
{
@@ -78,11 +80,16 @@
}
};
bool mPastFirstStatement;
+ bool mSeenNonPreprocessorToken; // Tracks if a non-preprocessor token has been seen yet. Some
+ // macros, such as
+ // #extension must be declared before all shader code.
std::vector<ConditionalBlock> mConditionalStack;
- Tokenizer* mTokenizer;
- MacroSet* mMacroSet;
- Diagnostics* mDiagnostics;
- DirectiveHandler* mDirectiveHandler;
+ Tokenizer *mTokenizer;
+ MacroSet *mMacroSet;
+ Diagnostics *mDiagnostics;
+ DirectiveHandler *mDirectiveHandler;
+ int mShaderVersion;
+ int mMaxMacroExpansionDepth;
};
} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/ExpressionParser.cpp b/src/OpenGL/compiler/preprocessor/ExpressionParser.cpp
index b2aa9d7..752252b 100644
--- a/src/OpenGL/compiler/preprocessor/ExpressionParser.cpp
+++ b/src/OpenGL/compiler/preprocessor/ExpressionParser.cpp
@@ -88,26 +88,38 @@
#if defined(__GNUC__)
// Triggered by the auto-generated pplval variable.
+#if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#else
#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
#elif defined(_MSC_VER)
-#pragma warning(disable: 4065 4701)
+#pragma warning(disable: 4065 4244 4701 4702)
#endif
#include "ExpressionParser.h"
+#if defined(_MSC_VER)
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+
+#include <limits>
#include <cassert>
#include <sstream>
+#include <stdint.h>
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "Lexer.h"
#include "Token.h"
+#include "../../common/debug.h"
-#if defined(_MSC_VER)
-typedef __int64 YYSTYPE;
-#else
-#include <stdint.h>
-typedef intmax_t YYSTYPE;
-#endif // _MSC_VER
+typedef int32_t YYSTYPE;
+typedef uint32_t UNSIGNED_TYPE;
+
+#define YYENABLE_NLS 0
+#define YYLTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_DECLARED 1
@@ -118,7 +130,17 @@
pp::Lexer* lexer;
pp::Token* token;
int* result;
- int shortCircuited; // Don't produce errors when > 0
+ bool parsePresetToken;
+
+ pp::ExpressionParser::ErrorSettings errorSettings;
+ bool *valid;
+
+ void startIgnoreErrors() { ++ignoreErrors; }
+ void endIgnoreErrors() { --ignoreErrors; }
+
+ bool isIgnoringErrors() { return ignoreErrors > 0; }
+
+ int ignoreErrors;
};
} // namespace
@@ -159,15 +181,16 @@
enum yytokentype
{
TOK_CONST_INT = 258,
- TOK_OP_OR = 259,
- TOK_OP_AND = 260,
- TOK_OP_EQ = 261,
- TOK_OP_NE = 262,
- TOK_OP_LE = 263,
- TOK_OP_GE = 264,
- TOK_OP_LEFT = 265,
- TOK_OP_RIGHT = 266,
- TOK_UNARY = 267
+ TOK_IDENTIFIER = 259,
+ TOK_OP_OR = 260,
+ TOK_OP_AND = 261,
+ TOK_OP_EQ = 262,
+ TOK_OP_NE = 263,
+ TOK_OP_LE = 264,
+ TOK_OP_GE = 265,
+ TOK_OP_LEFT = 266,
+ TOK_OP_RIGHT = 267,
+ TOK_UNARY = 268
};
#endif
@@ -426,23 +449,23 @@
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 14
+#define YYFINAL 15
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 178
+#define YYLAST 176
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 27
+#define YYNTOKENS 28
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 5
/* YYNRULES -- Number of rules. */
-#define YYNRULES 28
+#define YYNRULES 29
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 54
+#define YYNSTATES 55
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 267
+#define YYMAXUTOK 268
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -454,16 +477,16 @@
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 23, 2, 2, 2, 21, 8, 2,
- 25, 26, 19, 17, 2, 18, 2, 20, 2, 2,
+ 2, 2, 2, 24, 2, 2, 2, 22, 9, 2,
+ 26, 27, 20, 18, 2, 19, 2, 21, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 11, 2, 12, 2, 2, 2, 2, 2, 2, 2,
+ 12, 2, 13, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 7, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 8, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 6, 2, 24, 2, 2, 2,
+ 2, 2, 2, 2, 7, 2, 25, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -477,16 +500,16 @@
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
- 5, 9, 10, 13, 14, 15, 16, 22
+ 5, 6, 10, 11, 14, 15, 16, 17, 23
};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
-static const yytype_uint8 yyrline[] =
+static const yytype_uint16 yyrline[] =
{
- 0, 86, 86, 93, 94, 94, 110, 110, 126, 129,
- 132, 135, 138, 141, 144, 147, 150, 153, 156, 159,
- 162, 165, 184, 203, 206, 209, 212, 215, 218
+ 0, 125, 125, 132, 133, 144, 144, 165, 165, 186,
+ 189, 192, 195, 198, 201, 204, 207, 210, 213, 238,
+ 260, 263, 266, 292, 319, 322, 325, 328, 340, 343
};
#endif
@@ -495,11 +518,11 @@
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_OP_OR",
- "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE", "'<'",
- "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT", "'+'",
- "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", "')'",
- "$accept", "input", "expression", "$@1", "$@2", YY_NULLPTR
+ "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_IDENTIFIER",
+ "TOK_OP_OR", "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE",
+ "'<'", "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT",
+ "'+'", "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('",
+ "')'", "$accept", "input", "expression", "$@1", "$@2", YY_NULLPTR
};
#endif
@@ -508,16 +531,16 @@
(internal) symbol number NUM (which must be that of a token). */
static const yytype_uint16 yytoknum[] =
{
- 0, 256, 257, 258, 259, 260, 124, 94, 38, 261,
- 262, 60, 62, 263, 264, 265, 266, 43, 45, 42,
- 47, 37, 267, 33, 126, 40, 41
+ 0, 256, 257, 258, 259, 260, 261, 124, 94, 38,
+ 262, 263, 60, 62, 264, 265, 266, 267, 43, 45,
+ 42, 47, 37, 268, 33, 126, 40, 41
};
# endif
-#define YYPACT_NINF -11
+#define YYPACT_NINF -12
#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-11)))
+ (!!((Yystate) == (-12)))
#define YYTABLE_NINF -1
@@ -528,12 +551,12 @@
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- 49, -11, 49, 49, 49, 49, 49, 31, 71, -11,
- -11, -11, -11, 30, -11, -11, -11, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, -11, 49, 49, 119, 133, 146, 157,
- 157, -10, -10, -10, -10, 40, 40, -7, -7, -11,
- -11, -11, 88, 104
+ 31, -12, -12, 31, 31, 31, 31, 31, 51, 76,
+ -12, -12, -12, -12, 53, -12, -12, -12, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, -12, 31, 31, 124, 138, 26,
+ 149, 149, -11, -11, -11, -11, 154, 154, -8, -8,
+ -12, -12, -12, 93, 109
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -541,24 +564,24 @@
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
- 0, 3, 0, 0, 0, 0, 0, 0, 2, 27,
- 26, 24, 25, 0, 1, 4, 6, 0, 0, 0,
+ 0, 3, 4, 0, 0, 0, 0, 0, 0, 2,
+ 28, 27, 25, 26, 0, 1, 5, 7, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 28, 0, 0, 8, 9, 10, 12,
- 11, 16, 15, 14, 13, 18, 17, 20, 19, 23,
- 22, 21, 5, 7
+ 0, 0, 0, 0, 29, 0, 0, 9, 10, 11,
+ 13, 12, 17, 16, 15, 14, 19, 18, 21, 20,
+ 24, 23, 22, 6, 8
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -11, -11, -2, -11, -11
+ -12, -12, -3, -12, -12
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- -1, 7, 8, 34, 35
+ -1, 8, 9, 35, 36
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -566,74 +589,74 @@
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
- 9, 10, 11, 12, 13, 26, 27, 28, 29, 30,
- 31, 32, 30, 31, 32, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
- 51, 14, 52, 53, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 1, 0, 0, 0, 33, 28, 29, 30,
- 31, 32, 0, 0, 0, 0, 2, 3, 0, 0,
- 0, 0, 4, 5, 6, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 18, 19, 20, 21,
+ 10, 11, 12, 13, 14, 27, 28, 29, 30, 31,
+ 32, 33, 31, 32, 33, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 0, 53, 54, 1, 2, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 3,
+ 4, 15, 0, 0, 0, 5, 6, 7, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 0, 0, 0, 0,
+ 34, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32
+ 32, 33, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 29, 30, 31, 32, 33
};
static const yytype_int8 yycheck[] =
{
- 2, 3, 4, 5, 6, 15, 16, 17, 18, 19,
- 20, 21, 19, 20, 21, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 0, 34, 35, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 3, -1, -1, -1, 26, 17, 18, 19,
- 20, 21, -1, -1, -1, -1, 17, 18, -1, -1,
- -1, -1, 23, 24, 25, 4, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 7, 8, 9, 10,
+ 3, 4, 5, 6, 7, 16, 17, 18, 19, 20,
+ 21, 22, 20, 21, 22, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, -1, 35, 36, 3, 4, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 18,
+ 19, 0, -1, -1, -1, 24, 25, 26, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, -1, -1, -1, -1,
+ 27, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21
+ 21, 22, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 18, 19, 20, 21, 22
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
- 0, 3, 17, 18, 23, 24, 25, 28, 29, 29,
- 29, 29, 29, 29, 0, 4, 5, 6, 7, 8,
+ 0, 3, 4, 18, 19, 24, 25, 26, 29, 30,
+ 30, 30, 30, 30, 30, 0, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 26, 30, 31, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29
+ 19, 20, 21, 22, 27, 31, 32, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
- 0, 27, 28, 29, 30, 29, 31, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29, 29
+ 0, 28, 29, 30, 30, 31, 30, 32, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
- 0, 2, 1, 1, 0, 4, 0, 4, 3, 3,
+ 0, 2, 1, 1, 1, 0, 4, 0, 4, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 2, 2, 2, 2, 3
+ 3, 3, 3, 3, 3, 2, 2, 2, 2, 3
};
@@ -1327,10 +1350,15 @@
case 4:
{
- if ((yyvsp[-1]) != 0)
+ if (!context->isIgnoringErrors())
{
- context->shortCircuited++;
+ // This rule should be applied right after the token is lexed, so we can
+ // refer to context->token in the error message.
+ context->diagnostics->report(context->errorSettings.unexpectedIdentifier,
+ context->token->location, context->token->text);
+ *(context->valid) = false;
}
+ (yyval) = (yyvsp[0]);
}
break;
@@ -1338,10 +1366,26 @@
case 5:
{
+ if ((yyvsp[-1]) != 0)
+ {
+ // Ignore errors in the short-circuited part of the expression.
+ // ESSL3.00 section 3.4:
+ // If an operand is not evaluated, the presence of undefined identifiers
+ // in the operand will not cause an error.
+ // Unevaluated division by zero should not cause an error either.
+ context->startIgnoreErrors();
+ }
+ }
+
+ break;
+
+ case 6:
+
+ {
if ((yyvsp[-3]) != 0)
{
- context->shortCircuited--;
- (yyval) = 1;
+ context->endIgnoreErrors();
+ (yyval) = static_cast<YYSTYPE>(1);
}
else
{
@@ -1351,24 +1395,29 @@
break;
- case 6:
+ case 7:
{
if ((yyvsp[-1]) == 0)
{
- context->shortCircuited++;
+ // Ignore errors in the short-circuited part of the expression.
+ // ESSL3.00 section 3.4:
+ // If an operand is not evaluated, the presence of undefined identifiers
+ // in the operand will not cause an error.
+ // Unevaluated division by zero should not cause an error either.
+ context->startIgnoreErrors();
}
}
break;
- case 7:
+ case 8:
{
if ((yyvsp[-3]) == 0)
{
- context->shortCircuited--;
- (yyval) = 0;
+ context->endIgnoreErrors();
+ (yyval) = static_cast<YYSTYPE>(0);
}
else
{
@@ -1378,7 +1427,7 @@
break;
- case 8:
+ case 9:
{
(yyval) = (yyvsp[-2]) | (yyvsp[0]);
@@ -1386,7 +1435,7 @@
break;
- case 9:
+ case 10:
{
(yyval) = (yyvsp[-2]) ^ (yyvsp[0]);
@@ -1394,7 +1443,7 @@
break;
- case 10:
+ case 11:
{
(yyval) = (yyvsp[-2]) & (yyvsp[0]);
@@ -1402,7 +1451,7 @@
break;
- case 11:
+ case 12:
{
(yyval) = (yyvsp[-2]) != (yyvsp[0]);
@@ -1410,7 +1459,7 @@
break;
- case 12:
+ case 13:
{
(yyval) = (yyvsp[-2]) == (yyvsp[0]);
@@ -1418,7 +1467,7 @@
break;
- case 13:
+ case 14:
{
(yyval) = (yyvsp[-2]) >= (yyvsp[0]);
@@ -1426,7 +1475,7 @@
break;
- case 14:
+ case 15:
{
(yyval) = (yyvsp[-2]) <= (yyvsp[0]);
@@ -1434,7 +1483,7 @@
break;
- case 15:
+ case 16:
{
(yyval) = (yyvsp[-2]) > (yyvsp[0]);
@@ -1442,7 +1491,7 @@
break;
- case 16:
+ case 17:
{
(yyval) = (yyvsp[-2]) < (yyvsp[0]);
@@ -1450,18 +1499,32 @@
break;
- case 17:
-
- {
- (yyval) = (yyvsp[-2]) >> (yyvsp[0]);
- }
-
- break;
-
case 18:
{
- (yyval) = (yyvsp[-2]) << (yyvsp[0]);
+ if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << (yyvsp[-2]) << " >> " << (yyvsp[0]);
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
+ }
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else if ((yyvsp[-2]) < 0)
+ {
+ // Logical shift right.
+ (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) >> (yyvsp[0]));
+ }
+ else
+ {
+ (yyval) = (yyvsp[-2]) >> (yyvsp[0]);
+ }
}
break;
@@ -1469,7 +1532,26 @@
case 19:
{
- (yyval) = (yyvsp[-2]) - (yyvsp[0]);
+ if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << (yyvsp[-2]) << " << " << (yyvsp[0]);
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
+ }
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else
+ {
+ // Logical shift left. Casting to unsigned is needed to ensure there's no signed integer
+ // overflow, which some tools treat as an error.
+ (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0]));
+ }
}
break;
@@ -1477,7 +1559,7 @@
case 20:
{
- (yyval) = (yyvsp[-2]) + (yyvsp[0]);
+ (yyval) = (yyvsp[-2]) - (yyvsp[0]);
}
break;
@@ -1485,23 +1567,7 @@
case 21:
{
- if ((yyvsp[0]) == 0)
- {
- if (!context->shortCircuited)
- {
- context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
- context->token->location, "");
- YYABORT;
- }
- else
- {
- (yyval) = 0;
- }
- }
- else
- {
- (yyval) = (yyvsp[-2]) % (yyvsp[0]);
- }
+ (yyval) = (yyvsp[-2]) + (yyvsp[0]);
}
break;
@@ -1511,16 +1577,55 @@
{
if ((yyvsp[0]) == 0)
{
- if (!context->shortCircuited)
+ if (!context->isIgnoringErrors())
{
- context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
- context->token->location, "");
- YYABORT;
+ std::ostringstream stream;
+ stream << (yyvsp[-2]) << " % " << (yyvsp[0]);
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
}
- else
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else if (((yyvsp[-2]) == std::numeric_limits<YYSTYPE>::min()) && ((yyvsp[0]) == -1))
+ {
+ // Check for the special case where the minimum representable number is
+ // divided by -1. If left alone this has undefined results.
+ (yyval) = 0;
+ }
+ else
+ {
+ (yyval) = (yyvsp[-2]) % (yyvsp[0]);
+ }
+ }
+
+ break;
+
+ case 23:
+
+ {
+ if ((yyvsp[0]) == 0)
+ {
+ if (!context->isIgnoringErrors())
{
- (yyval) = 0;
+ std::ostringstream stream;
+ stream << (yyvsp[-2]) << " / " << (yyvsp[0]);
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
}
+ (yyval) = static_cast<YYSTYPE>(0);
+ }
+ else if (((yyvsp[-2]) == std::numeric_limits<YYSTYPE>::min()) && ((yyvsp[0]) == -1))
+ {
+ // Check for the special case where the minimum representable number is
+ // divided by -1. If left alone this leads to integer overflow in C++, which
+ // has undefined results.
+ (yyval) = std::numeric_limits<YYSTYPE>::max();
}
else
{
@@ -1530,7 +1635,7 @@
break;
- case 23:
+ case 24:
{
(yyval) = (yyvsp[-2]) * (yyvsp[0]);
@@ -1538,7 +1643,7 @@
break;
- case 24:
+ case 25:
{
(yyval) = ! (yyvsp[0]);
@@ -1546,7 +1651,7 @@
break;
- case 25:
+ case 26:
{
(yyval) = ~ (yyvsp[0]);
@@ -1554,15 +1659,24 @@
break;
- case 26:
+ case 27:
{
- (yyval) = - (yyvsp[0]);
+ // Check for negation of minimum representable integer to prevent undefined signed int
+ // overflow.
+ if ((yyvsp[0]) == std::numeric_limits<YYSTYPE>::min())
+ {
+ (yyval) = std::numeric_limits<YYSTYPE>::min();
+ }
+ else
+ {
+ (yyval) = -(yyvsp[0]);
+ }
}
break;
- case 27:
+ case 28:
{
(yyval) = + (yyvsp[0]);
@@ -1570,7 +1684,7 @@
break;
- case 28:
+ case 29:
{
(yyval) = (yyvsp[-1]);
@@ -1810,93 +1924,115 @@
-int yylex(YYSTYPE* lvalp, Context* context)
+int yylex(YYSTYPE *lvalp, Context *context)
{
+ pp::Token *token = context->token;
+ if (!context->parsePresetToken)
+ {
+ context->lexer->lex(token);
+ }
+ context->parsePresetToken = false;
+
int type = 0;
- pp::Token* token = context->token;
switch (token->type)
{
- case pp::Token::CONST_INT:
- {
+ case pp::Token::CONST_INT: {
unsigned int val = 0;
- if (!token->uValue(&val))
+ int testVal = 0;
+ if (!token->uValue(&val) || (!token->iValue(&testVal) &&
+ context->errorSettings.integerLiteralsMustFit32BitSignedRange))
{
- context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW,
+ context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW,
token->location, token->text);
+ *(context->valid) = false;
}
*lvalp = static_cast<YYSTYPE>(val);
type = TOK_CONST_INT;
break;
}
case pp::Token::IDENTIFIER:
- if (!context->shortCircuited)
- {
- // Defined identifiers should have been expanded already.
- // Unlike the C/C++ preprocessor, it does not default to 0.
- // Use of such identifiers causes an error.
- context->diagnostics->report(pp::Diagnostics::UNDEFINED_IDENTIFIER,
- token->location, token->text);
- }
-
- *lvalp = 0;
- type = TOK_CONST_INT;
+ *lvalp = static_cast<YYSTYPE>(-1);
+ type = TOK_IDENTIFIER;
break;
- case pp::Token::OP_OR: type = TOK_OP_OR; break;
- case pp::Token::OP_AND: type = TOK_OP_AND; break;
- case pp::Token::OP_NE: type = TOK_OP_NE; break;
- case pp::Token::OP_EQ: type = TOK_OP_EQ; break;
- case pp::Token::OP_GE: type = TOK_OP_GE; break;
- case pp::Token::OP_LE: type = TOK_OP_LE; break;
- case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break;
- case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break;
- case '|': type = '|'; break;
- case '^': type = '^'; break;
- case '&': type = '&'; break;
- case '>': type = '>'; break;
- case '<': type = '<'; break;
- case '-': type = '-'; break;
- case '+': type = '+'; break;
- case '%': type = '%'; break;
- case '/': type = '/'; break;
- case '*': type = '*'; break;
- case '!': type = '!'; break;
- case '~': type = '~'; break;
- case '(': type = '('; break;
- case ')': type = ')'; break;
+ case pp::Token::OP_OR:
+ type = TOK_OP_OR;
+ break;
+ case pp::Token::OP_AND:
+ type = TOK_OP_AND;
+ break;
+ case pp::Token::OP_NE:
+ type = TOK_OP_NE;
+ break;
+ case pp::Token::OP_EQ:
+ type = TOK_OP_EQ;
+ break;
+ case pp::Token::OP_GE:
+ type = TOK_OP_GE;
+ break;
+ case pp::Token::OP_LE:
+ type = TOK_OP_LE;
+ break;
+ case pp::Token::OP_RIGHT:
+ type = TOK_OP_RIGHT;
+ break;
+ case pp::Token::OP_LEFT:
+ type = TOK_OP_LEFT;
+ break;
+ case '|':
+ case '^':
+ case '&':
+ case '>':
+ case '<':
+ case '-':
+ case '+':
+ case '%':
+ case '/':
+ case '*':
+ case '!':
+ case '~':
+ case '(':
+ case ')':
+ type = token->type;
+ break;
- default: break;
+ default:
+ break;
}
- // Advance to the next token if the current one is valid.
- if (type != 0) context->lexer->lex(token);
-
return type;
}
-void yyerror(Context* context, const char* reason)
+void yyerror(Context *context, const char *reason)
{
- context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION,
+ context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION,
context->token->location,
reason);
}
namespace pp {
-ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) :
- mLexer(lexer),
- mDiagnostics(diagnostics)
+ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics)
+ : mLexer(lexer),
+ mDiagnostics(diagnostics)
{
}
-bool ExpressionParser::parse(Token* token, int* result)
+bool ExpressionParser::parse(Token *token,
+ int *result,
+ bool parsePresetToken,
+ const ErrorSettings &errorSettings,
+ bool *valid)
{
Context context;
context.diagnostics = mDiagnostics;
context.lexer = mLexer;
context.token = token;
context.result = result;
- context.shortCircuited = 0;
+ context.ignoreErrors = 0;
+ context.parsePresetToken = parsePresetToken;
+ context.errorSettings = errorSettings;
+ context.valid = valid;
int ret = yyparse(&context);
switch (ret)
{
@@ -1905,12 +2041,12 @@
break;
case 2:
- mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, "");
+ mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, "");
break;
default:
assert(false);
- mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, "");
+ mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, "");
break;
}
diff --git a/src/OpenGL/compiler/preprocessor/ExpressionParser.h b/src/OpenGL/compiler/preprocessor/ExpressionParser.h
index c28f4bb..47bd477 100644
--- a/src/OpenGL/compiler/preprocessor/ExpressionParser.h
+++ b/src/OpenGL/compiler/preprocessor/ExpressionParser.h
@@ -15,27 +15,34 @@
#ifndef COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
#define COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
-#include "pp_utils.h"
+#include "DiagnosticsBase.h"
namespace pp
{
-class Diagnostics;
class Lexer;
struct Token;
class ExpressionParser
{
public:
- ExpressionParser(Lexer* lexer, Diagnostics* diagnostics);
+ struct ErrorSettings
+ {
+ Diagnostics::ID unexpectedIdentifier;
+ bool integerLiteralsMustFit32BitSignedRange;
+ };
- bool parse(Token* token, int* result);
+ ExpressionParser(Lexer *lexer, Diagnostics *diagnostics);
+
+ bool parse(Token *token,
+ int *result,
+ bool parsePresetToken,
+ const ErrorSettings &errorSettings,
+ bool *valid);
private:
- PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser);
-
- Lexer* mLexer;
- Diagnostics* mDiagnostics;
+ Lexer *mLexer;
+ Diagnostics *mDiagnostics;
};
} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/ExpressionParser.y b/src/OpenGL/compiler/preprocessor/ExpressionParser.y
index 09e86aa..5342935 100644
--- a/src/OpenGL/compiler/preprocessor/ExpressionParser.y
+++ b/src/OpenGL/compiler/preprocessor/ExpressionParser.y
@@ -38,26 +38,38 @@
#if defined(__GNUC__)
// Triggered by the auto-generated pplval variable.
+#if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#else
#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
#elif defined(_MSC_VER)
-#pragma warning(disable: 4065 4701)
+#pragma warning(disable: 4065 4244 4701 4702)
#endif
#include "ExpressionParser.h"
+#if defined(_MSC_VER)
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+
+#include <limits>
#include <cassert>
#include <sstream>
+#include <stdint.h>
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "Lexer.h"
#include "Token.h"
+#include "../../common/debug.h"
-#if defined(_MSC_VER)
-typedef __int64 YYSTYPE;
-#else
-#include <stdint.h>
-typedef intmax_t YYSTYPE;
-#endif // _MSC_VER
+typedef int32_t YYSTYPE;
+typedef uint32_t UNSIGNED_TYPE;
+
+#define YYENABLE_NLS 0
+#define YYLTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_DECLARED 1
@@ -68,7 +80,17 @@
pp::Lexer* lexer;
pp::Token* token;
int* result;
- int shortCircuited; // Don't produce errors when > 0
+ bool parsePresetToken;
+
+ pp::ExpressionParser::ErrorSettings errorSettings;
+ bool *valid;
+
+ void startIgnoreErrors() { ++ignoreErrors; }
+ void endIgnoreErrors() { --ignoreErrors; }
+
+ bool isIgnoringErrors() { return ignoreErrors > 0; }
+
+ int ignoreErrors;
};
} // namespace
%}
@@ -84,6 +106,7 @@
%}
%token TOK_CONST_INT
+%token TOK_IDENTIFIER
%left TOK_OP_OR
%left TOK_OP_AND
%left '|'
@@ -107,16 +130,32 @@
expression
: TOK_CONST_INT
+ | TOK_IDENTIFIER {
+ if (!context->isIgnoringErrors())
+ {
+ // This rule should be applied right after the token is lexed, so we can
+ // refer to context->token in the error message.
+ context->diagnostics->report(context->errorSettings.unexpectedIdentifier,
+ context->token->location, context->token->text);
+ *(context->valid) = false;
+ }
+ $$ = $1;
+ }
| expression TOK_OP_OR {
if ($1 != 0)
{
- context->shortCircuited++;
+ // Ignore errors in the short-circuited part of the expression.
+ // ESSL3.00 section 3.4:
+ // If an operand is not evaluated, the presence of undefined identifiers
+ // in the operand will not cause an error.
+ // Unevaluated division by zero should not cause an error either.
+ context->startIgnoreErrors();
}
} expression {
if ($1 != 0)
{
- context->shortCircuited--;
- $$ = 1;
+ context->endIgnoreErrors();
+ $$ = static_cast<YYSTYPE>(1);
}
else
{
@@ -126,13 +165,18 @@
| expression TOK_OP_AND {
if ($1 == 0)
{
- context->shortCircuited++;
+ // Ignore errors in the short-circuited part of the expression.
+ // ESSL3.00 section 3.4:
+ // If an operand is not evaluated, the presence of undefined identifiers
+ // in the operand will not cause an error.
+ // Unevaluated division by zero should not cause an error either.
+ context->startIgnoreErrors();
}
} expression {
if ($1 == 0)
{
- context->shortCircuited--;
- $$ = 0;
+ context->endIgnoreErrors();
+ $$ = static_cast<YYSTYPE>(0);
}
else
{
@@ -167,10 +211,51 @@
$$ = $1 < $3;
}
| expression TOK_OP_RIGHT expression {
- $$ = $1 >> $3;
+ if ($3 < 0 || $3 > 31)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << $1 << " >> " << $3;
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
+ }
+ $$ = static_cast<YYSTYPE>(0);
+ }
+ else if ($1 < 0)
+ {
+ // Logical shift right.
+ $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) >> $3);
+ }
+ else
+ {
+ $$ = $1 >> $3;
+ }
}
| expression TOK_OP_LEFT expression {
- $$ = $1 << $3;
+ if ($3 < 0 || $3 > 31)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << $1 << " << " << $3;
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
+ }
+ $$ = static_cast<YYSTYPE>(0);
+ }
+ else
+ {
+ // Logical shift left. Casting to unsigned is needed to ensure there's no signed integer
+ // overflow, which some tools treat as an error.
+ $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3);
+ }
}
| expression '-' expression {
$$ = $1 - $3;
@@ -181,16 +266,23 @@
| expression '%' expression {
if ($3 == 0)
{
- if (!context->shortCircuited)
+ if (!context->isIgnoringErrors())
{
- context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
- context->token->location, "");
- YYABORT;
+ std::ostringstream stream;
+ stream << $1 << " % " << $3;
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
}
- else
- {
- $$ = 0;
- }
+ $$ = static_cast<YYSTYPE>(0);
+ }
+ else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
+ {
+ // Check for the special case where the minimum representable number is
+ // divided by -1. If left alone this has undefined results.
+ $$ = 0;
}
else
{
@@ -200,16 +292,24 @@
| expression '/' expression {
if ($3 == 0)
{
- if (!context->shortCircuited)
+ if (!context->isIgnoringErrors())
{
- context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
- context->token->location, "");
- YYABORT;
+ std::ostringstream stream;
+ stream << $1 << " / " << $3;
+ std::string text = stream.str();
+ context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
+ context->token->location,
+ text.c_str());
+ *(context->valid) = false;
}
- else
- {
- $$ = 0;
- }
+ $$ = static_cast<YYSTYPE>(0);
+ }
+ else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
+ {
+ // Check for the special case where the minimum representable number is
+ // divided by -1. If left alone this leads to integer overflow in C++, which
+ // has undefined results.
+ $$ = std::numeric_limits<YYSTYPE>::max();
}
else
{
@@ -226,7 +326,16 @@
$$ = ~ $2;
}
| '-' expression %prec TOK_UNARY {
- $$ = - $2;
+ // Check for negation of minimum representable integer to prevent undefined signed int
+ // overflow.
+ if ($2 == std::numeric_limits<YYSTYPE>::min())
+ {
+ $$ = std::numeric_limits<YYSTYPE>::min();
+ }
+ else
+ {
+ $$ = -$2;
+ }
}
| '+' expression %prec TOK_UNARY {
$$ = + $2;
@@ -238,93 +347,115 @@
%%
-int yylex(YYSTYPE* lvalp, Context* context)
+int yylex(YYSTYPE *lvalp, Context *context)
{
+ pp::Token *token = context->token;
+ if (!context->parsePresetToken)
+ {
+ context->lexer->lex(token);
+ }
+ context->parsePresetToken = false;
+
int type = 0;
- pp::Token* token = context->token;
switch (token->type)
{
- case pp::Token::CONST_INT:
- {
+ case pp::Token::CONST_INT: {
unsigned int val = 0;
- if (!token->uValue(&val))
+ int testVal = 0;
+ if (!token->uValue(&val) || (!token->iValue(&testVal) &&
+ context->errorSettings.integerLiteralsMustFit32BitSignedRange))
{
- context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW,
+ context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW,
token->location, token->text);
+ *(context->valid) = false;
}
*lvalp = static_cast<YYSTYPE>(val);
type = TOK_CONST_INT;
break;
}
case pp::Token::IDENTIFIER:
- if (!context->shortCircuited)
- {
- // Defined identifiers should have been expanded already.
- // Unlike the C/C++ preprocessor, it does not default to 0.
- // Use of such identifiers causes an error.
- context->diagnostics->report(pp::Diagnostics::UNDEFINED_IDENTIFIER,
- token->location, token->text);
- }
-
- *lvalp = 0;
- type = TOK_CONST_INT;
+ *lvalp = static_cast<YYSTYPE>(-1);
+ type = TOK_IDENTIFIER;
break;
- case pp::Token::OP_OR: type = TOK_OP_OR; break;
- case pp::Token::OP_AND: type = TOK_OP_AND; break;
- case pp::Token::OP_NE: type = TOK_OP_NE; break;
- case pp::Token::OP_EQ: type = TOK_OP_EQ; break;
- case pp::Token::OP_GE: type = TOK_OP_GE; break;
- case pp::Token::OP_LE: type = TOK_OP_LE; break;
- case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break;
- case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break;
- case '|': type = '|'; break;
- case '^': type = '^'; break;
- case '&': type = '&'; break;
- case '>': type = '>'; break;
- case '<': type = '<'; break;
- case '-': type = '-'; break;
- case '+': type = '+'; break;
- case '%': type = '%'; break;
- case '/': type = '/'; break;
- case '*': type = '*'; break;
- case '!': type = '!'; break;
- case '~': type = '~'; break;
- case '(': type = '('; break;
- case ')': type = ')'; break;
+ case pp::Token::OP_OR:
+ type = TOK_OP_OR;
+ break;
+ case pp::Token::OP_AND:
+ type = TOK_OP_AND;
+ break;
+ case pp::Token::OP_NE:
+ type = TOK_OP_NE;
+ break;
+ case pp::Token::OP_EQ:
+ type = TOK_OP_EQ;
+ break;
+ case pp::Token::OP_GE:
+ type = TOK_OP_GE;
+ break;
+ case pp::Token::OP_LE:
+ type = TOK_OP_LE;
+ break;
+ case pp::Token::OP_RIGHT:
+ type = TOK_OP_RIGHT;
+ break;
+ case pp::Token::OP_LEFT:
+ type = TOK_OP_LEFT;
+ break;
+ case '|':
+ case '^':
+ case '&':
+ case '>':
+ case '<':
+ case '-':
+ case '+':
+ case '%':
+ case '/':
+ case '*':
+ case '!':
+ case '~':
+ case '(':
+ case ')':
+ type = token->type;
+ break;
- default: break;
+ default:
+ break;
}
- // Advance to the next token if the current one is valid.
- if (type != 0) context->lexer->lex(token);
-
return type;
}
-void yyerror(Context* context, const char* reason)
+void yyerror(Context *context, const char *reason)
{
- context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION,
+ context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION,
context->token->location,
reason);
}
namespace pp {
-ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) :
- mLexer(lexer),
- mDiagnostics(diagnostics)
+ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics)
+ : mLexer(lexer),
+ mDiagnostics(diagnostics)
{
}
-bool ExpressionParser::parse(Token* token, int* result)
+bool ExpressionParser::parse(Token *token,
+ int *result,
+ bool parsePresetToken,
+ const ErrorSettings &errorSettings,
+ bool *valid)
{
Context context;
context.diagnostics = mDiagnostics;
context.lexer = mLexer;
context.token = token;
context.result = result;
- context.shortCircuited = 0;
+ context.ignoreErrors = 0;
+ context.parsePresetToken = parsePresetToken;
+ context.errorSettings = errorSettings;
+ context.valid = valid;
int ret = yyparse(&context);
switch (ret)
{
@@ -333,12 +464,12 @@
break;
case 2:
- mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, "");
+ mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, "");
break;
default:
assert(false);
- mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, "");
+ mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, "");
break;
}
diff --git a/src/OpenGL/compiler/preprocessor/Input.cpp b/src/OpenGL/compiler/preprocessor/Input.cpp
index c22622a..0626af7 100644
--- a/src/OpenGL/compiler/preprocessor/Input.cpp
+++ b/src/OpenGL/compiler/preprocessor/Input.cpp
@@ -25,27 +25,101 @@
{
}
-Input::Input(int count, const char* const string[], const int length[]) :
- mCount(count),
- mString(string)
+Input::~Input()
{
- assert(mCount >= 0);
+}
+
+Input::Input(size_t count, const char *const string[], const int length[])
+ : mCount(count), mString(string)
+{
mLength.reserve(mCount);
- for (int i = 0; i < mCount; ++i)
+ for (size_t i = 0; i < mCount; ++i)
{
int len = length ? length[i] : -1;
- mLength.push_back(len < 0 ? strlen(mString[i]) : len);
+ mLength.push_back(len < 0 ? std::strlen(mString[i]) : len);
}
}
-int Input::read(char* buf, int maxSize)
+const char *Input::skipChar()
{
- int nRead = 0;
- while ((nRead < maxSize) && (mReadLoc.sIndex < mCount))
+ // This function should only be called when there is a character to skip.
+ assert(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
+ ++mReadLoc.cIndex;
+ if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
{
- int size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
- size = std::min(size, maxSize);
- memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
+ ++mReadLoc.sIndex;
+ mReadLoc.cIndex = 0;
+ }
+ if (mReadLoc.sIndex >= mCount)
+ {
+ return nullptr;
+ }
+ return mString[mReadLoc.sIndex] + mReadLoc.cIndex;
+}
+
+size_t Input::read(char *buf, size_t maxSize, int *lineNo)
+{
+ size_t nRead = 0;
+ // The previous call to read might have stopped copying the string when encountering a line
+ // continuation. Check for this possibility first.
+ if (mReadLoc.sIndex < mCount && maxSize > 0)
+ {
+ const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex;
+ if ((*c) == '\\')
+ {
+ c = skipChar();
+ if (c != nullptr && (*c) == '\n')
+ {
+ // Line continuation of backslash + newline.
+ skipChar();
+ // Fake an EOF if the line number would overflow.
+ if (*lineNo == INT_MAX)
+ {
+ return 0;
+ }
+ ++(*lineNo);
+ }
+ else if (c != nullptr && (*c) == '\r')
+ {
+ // Line continuation. Could be backslash + '\r\n' or just backslash + '\r'.
+ c = skipChar();
+ if (c != nullptr && (*c) == '\n')
+ {
+ skipChar();
+ }
+ // Fake an EOF if the line number would overflow.
+ if (*lineNo == INT_MAX)
+ {
+ return 0;
+ }
+ ++(*lineNo);
+ }
+ else
+ {
+ // Not line continuation, so write the skipped backslash to buf.
+ *buf = '\\';
+ ++nRead;
+ }
+ }
+ }
+
+ size_t maxRead = maxSize;
+ while ((nRead < maxRead) && (mReadLoc.sIndex < mCount))
+ {
+ size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
+ size = std::min(size, maxSize);
+ for (size_t i = 0; i < size; ++i)
+ {
+ // Stop if a possible line continuation is encountered.
+ // It will be processed on the next call on input, which skips it
+ // and increments line number if necessary.
+ if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\')
+ {
+ size = i;
+ maxRead = nRead + size; // Stop reading right before the backslash.
+ }
+ }
+ std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
nRead += size;
mReadLoc.cIndex += size;
diff --git a/src/OpenGL/compiler/preprocessor/Input.h b/src/OpenGL/compiler/preprocessor/Input.h
index 35776e7..59083bf 100644
--- a/src/OpenGL/compiler/preprocessor/Input.h
+++ b/src/OpenGL/compiler/preprocessor/Input.h
@@ -15,7 +15,9 @@
#ifndef COMPILER_PREPROCESSOR_INPUT_H_
#define COMPILER_PREPROCESSOR_INPUT_H_
+#include <cstddef>
#include <vector>
+#include <climits>
namespace pp
{
@@ -25,28 +27,33 @@
{
public:
Input();
- Input(int count, const char* const string[], const int length[]);
+ ~Input();
+ Input(size_t count, const char *const string[], const int length[]);
- int count() const { return mCount; }
- const char* string(int index) const { return mString[index]; }
- int length(int index) const { return mLength[index]; }
+ size_t count() const { return mCount; }
+ const char *string(size_t index) const { return mString[index]; }
+ size_t length(size_t index) const { return mLength[index]; }
- int read(char* buf, int maxSize);
+ size_t read(char *buf, size_t maxSize, int *lineNo);
struct Location
{
- int sIndex; // String index;
- int cIndex; // Char index.
+ size_t sIndex; // String index;
+ size_t cIndex; // Char index.
- Location() : sIndex(0), cIndex(0) { }
+ Location() : sIndex(0), cIndex(0) {}
};
- const Location& readLoc() const { return mReadLoc; }
+ const Location &readLoc() const { return mReadLoc; }
private:
+ // Skip a character and return the next character after the one that was skipped.
+ // Return nullptr if data runs out.
+ const char *skipChar();
+
// Input.
- int mCount;
- const char* const* mString;
- std::vector<int> mLength;
+ size_t mCount;
+ const char *const *mString;
+ std::vector<size_t> mLength;
Location mReadLoc;
};
diff --git a/src/OpenGL/compiler/preprocessor/Lexer.h b/src/OpenGL/compiler/preprocessor/Lexer.h
index 558fc98..54de516 100644
--- a/src/OpenGL/compiler/preprocessor/Lexer.h
+++ b/src/OpenGL/compiler/preprocessor/Lexer.h
@@ -25,7 +25,7 @@
public:
virtual ~Lexer();
- virtual void lex(Token* token) = 0;
+ virtual void lex(Token *token) = 0;
};
} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/Macro.cpp b/src/OpenGL/compiler/preprocessor/Macro.cpp
index 9024f8a..d3b419c 100644
--- a/src/OpenGL/compiler/preprocessor/Macro.cpp
+++ b/src/OpenGL/compiler/preprocessor/Macro.cpp
@@ -19,12 +19,33 @@
namespace pp
{
-bool Macro::equals(const Macro& other) const
+Macro::Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj)
{
- return (type == other.type) &&
- (name == other.name) &&
- (parameters == other.parameters) &&
- (replacements == other.replacements);
+}
+
+Macro::~Macro()
+{
+}
+
+bool Macro::equals(const Macro &other) const
+{
+ return (type == other.type) && (name == other.name) && (parameters == other.parameters) &&
+ (replacements == other.replacements);
+}
+
+void PredefineMacro(MacroSet *macroSet, const char *name, int value)
+{
+ Token token;
+ token.type = Token::CONST_INT;
+ token.text = std::to_string(value);
+
+ std::shared_ptr<Macro> macro = std::make_shared<Macro>();
+ macro->predefined = true;
+ macro->type = Macro::kTypeObj;
+ macro->name = name;
+ macro->replacements.push_back(token);
+
+ (*macroSet)[name] = macro;
}
} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/Macro.h b/src/OpenGL/compiler/preprocessor/Macro.h
index bad8db3..c2daeca 100644
--- a/src/OpenGL/compiler/preprocessor/Macro.h
+++ b/src/OpenGL/compiler/preprocessor/Macro.h
@@ -16,6 +16,7 @@
#define COMPILER_PREPROCESSOR_MACRO_H_
#include <map>
+#include <memory>
#include <string>
#include <vector>
@@ -34,11 +35,13 @@
typedef std::vector<std::string> Parameters;
typedef std::vector<Token> Replacements;
- Macro() : predefined(false), disabled(false), type(kTypeObj) { }
- bool equals(const Macro& other) const;
+ Macro();
+ ~Macro();
+ bool equals(const Macro &other) const;
bool predefined;
mutable bool disabled;
+ mutable int expansionCount;
Type type;
std::string name;
@@ -46,7 +49,9 @@
Replacements replacements;
};
-typedef std::map<std::string, Macro> MacroSet;
+typedef std::map<std::string, std::shared_ptr<Macro>> MacroSet;
+
+void PredefineMacro(MacroSet *macroSet, const char *name, int value);
} // namespace pp
#endif // COMPILER_PREPROCESSOR_MACRO_H_
diff --git a/src/OpenGL/compiler/preprocessor/MacroExpander.cpp b/src/OpenGL/compiler/preprocessor/MacroExpander.cpp
index df0e495..a235112 100644
--- a/src/OpenGL/compiler/preprocessor/MacroExpander.cpp
+++ b/src/OpenGL/compiler/preprocessor/MacroExpander.cpp
@@ -15,26 +15,32 @@
#include "MacroExpander.h"
#include <algorithm>
-#include <sstream>
+#include <cassert>
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
+#include "pp_utils.h"
#include "Token.h"
namespace pp
{
+namespace
+{
+
+const size_t kMaxContextTokens = 10000;
+
class TokenLexer : public Lexer
{
public:
typedef std::vector<Token> TokenVector;
- TokenLexer(TokenVector* tokens)
+ TokenLexer(TokenVector *tokens)
{
tokens->swap(mTokens);
mIter = mTokens.begin();
}
- virtual void lex(Token* token)
+ void lex(Token *token) override
{
if (mIter == mTokens.end())
{
@@ -54,26 +60,64 @@
TokenVector::const_iterator mIter;
};
-MacroExpander::MacroExpander(Lexer* lexer,
- MacroSet* macroSet,
- Diagnostics* diagnostics,
- bool parseDefined) :
- mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mParseDefined(parseDefined)
+} // anonymous namespace
+
+class MacroExpander::ScopedMacroReenabler final
{
- mReserveToken = nullptr;
+ public:
+ ScopedMacroReenabler(MacroExpander *expander);
+ ~ScopedMacroReenabler();
+
+ private:
+ PP_DISALLOW_COPY_AND_ASSIGN(ScopedMacroReenabler);
+
+ MacroExpander *mExpander;
+};
+
+MacroExpander::ScopedMacroReenabler::ScopedMacroReenabler(MacroExpander *expander)
+ : mExpander(expander)
+{
+ mExpander->mDeferReenablingMacros = true;
+}
+
+MacroExpander::ScopedMacroReenabler::~ScopedMacroReenabler()
+{
+ mExpander->mDeferReenablingMacros = false;
+ for (auto macro : mExpander->mMacrosToReenable)
+ {
+ // Copying the string here by using substr is a check for use-after-free. It detects
+ // use-after-free more reliably than just toggling the disabled flag.
+ assert(macro->name.substr() != "");
+ macro->disabled = false;
+ }
+ mExpander->mMacrosToReenable.clear();
+}
+
+MacroExpander::MacroExpander(Lexer *lexer,
+ MacroSet *macroSet,
+ Diagnostics *diagnostics,
+ bool parseDefined,
+ int allowedMacroExpansionDepth)
+ : mLexer(lexer),
+ mMacroSet(macroSet),
+ mDiagnostics(diagnostics),
+ mParseDefined(parseDefined),
+ mTotalTokensInContexts(0),
+ mAllowedMacroExpansionDepth(allowedMacroExpansionDepth),
+ mDeferReenablingMacros(false)
+{
}
MacroExpander::~MacroExpander()
{
- for (size_t i = 0; i < mContextStack.size(); ++i)
+ assert(mMacrosToReenable.empty());
+ for (MacroContext *context : mContextStack)
{
- delete mContextStack[i];
+ delete context;
}
-
- delete mReserveToken;
}
-void MacroExpander::lex(Token* token)
+void MacroExpander::lex(Token *token)
{
while (true)
{
@@ -98,7 +142,7 @@
}
if (token->type != Token::IDENTIFIER)
{
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, token->location,
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
token->text);
break;
}
@@ -110,7 +154,7 @@
getToken(token);
if (token->type != ')')
{
- mDiagnostics->report(Diagnostics::UNEXPECTED_TOKEN, token->location,
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
token->text);
break;
}
@@ -130,17 +174,22 @@
if (iter == mMacroSet->end())
break;
- const Macro& macro = iter->second;
- if (macro.disabled)
+ std::shared_ptr<Macro> macro = iter->second;
+ if (macro->disabled)
{
// If a particular token is not expanded, it is never expanded.
token->setExpansionDisabled(true);
break;
}
- if ((macro.type == Macro::kTypeFunc) && !isNextTokenLeftParen())
+
+ // Bump the expansion count before peeking if the next token is a '('
+ // otherwise there could be a #undef of the macro before the next token.
+ macro->expansionCount++;
+ if ((macro->type == Macro::kTypeFunc) && !isNextTokenLeftParen())
{
// If the token immediately after the macro name is not a '(',
// this macro should not be expanded.
+ macro->expansionCount--;
break;
}
@@ -148,13 +197,12 @@
}
}
-void MacroExpander::getToken(Token* token)
+void MacroExpander::getToken(Token *token)
{
- if (mReserveToken)
+ if (mReserveToken.get())
{
*token = *mReserveToken;
- delete mReserveToken;
- mReserveToken = nullptr;
+ mReserveToken.reset();
return;
}
@@ -170,22 +218,23 @@
}
else
{
+ assert(mTotalTokensInContexts == 0);
mLexer->lex(token);
}
}
-void MacroExpander::ungetToken(const Token& token)
+void MacroExpander::ungetToken(const Token &token)
{
if (!mContextStack.empty())
{
- MacroContext* context = mContextStack.back();
+ MacroContext *context = mContextStack.back();
context->unget();
assert(context->replacements[context->index] == token);
}
else
{
- assert(!mReserveToken);
- mReserveToken = new Token(token);
+ assert(!mReserveToken.get());
+ mReserveToken.reset(new Token(token));
}
}
@@ -200,24 +249,25 @@
return lparen;
}
-bool MacroExpander::pushMacro(const Macro& macro, const Token& identifier)
+bool MacroExpander::pushMacro(std::shared_ptr<Macro> macro, const Token &identifier)
{
- assert(!macro.disabled);
+ assert(!macro->disabled);
assert(!identifier.expansionDisabled());
assert(identifier.type == Token::IDENTIFIER);
- assert(identifier.text == macro.name);
+ assert(identifier.text == macro->name);
std::vector<Token> replacements;
- if (!expandMacro(macro, identifier, &replacements))
+ if (!expandMacro(*macro, identifier, &replacements))
return false;
// Macro is disabled for expansion until it is popped off the stack.
- macro.disabled = true;
+ macro->disabled = true;
- MacroContext* context = new MacroContext;
- context->macro = ¯o;
+ MacroContext *context = new MacroContext;
+ context->macro = macro;
context->replacements.swap(replacements);
mContextStack.push_back(context);
+ mTotalTokensInContexts += context->replacements.size();
return true;
}
@@ -225,43 +275,54 @@
{
assert(!mContextStack.empty());
- MacroContext* context = mContextStack.back();
+ MacroContext *context = mContextStack.back();
mContextStack.pop_back();
assert(context->empty());
assert(context->macro->disabled);
- context->macro->disabled = false;
+ assert(context->macro->expansionCount > 0);
+ if (mDeferReenablingMacros)
+ {
+ mMacrosToReenable.push_back(context->macro);
+ }
+ else
+ {
+ context->macro->disabled = false;
+ }
+ context->macro->expansionCount--;
+ mTotalTokensInContexts -= context->replacements.size();
delete context;
}
-bool MacroExpander::expandMacro(const Macro& macro,
- const Token& identifier,
- std::vector<Token>* replacements)
+bool MacroExpander::expandMacro(const Macro ¯o,
+ const Token &identifier,
+ std::vector<Token> *replacements)
{
replacements->clear();
+
+ // In the case of an object-like macro, the replacement list gets its location
+ // from the identifier, but in the case of a function-like macro, the replacement
+ // list gets its location from the closing parenthesis of the macro invocation.
+ // This is tested by dEQP-GLES3.functional.shaders.preprocessor.predefined_macros.*
+ SourceLocation replacementLocation = identifier.location;
if (macro.type == Macro::kTypeObj)
{
- replacements->assign(macro.replacements.begin(),
- macro.replacements.end());
+ replacements->assign(macro.replacements.begin(), macro.replacements.end());
if (macro.predefined)
{
- static const std::string kLine = "__LINE__";
- static const std::string kFile = "__FILE__";
+ const char kLine[] = "__LINE__";
+ const char kFile[] = "__FILE__";
assert(replacements->size() == 1);
- Token& repl = replacements->front();
+ Token &repl = replacements->front();
if (macro.name == kLine)
{
- std::ostringstream stream;
- stream << identifier.location.line;
- repl.text = stream.str();
+ repl.text = std::to_string(identifier.location.line);
}
else if (macro.name == kFile)
{
- std::ostringstream stream;
- stream << identifier.location.file;
- repl.text = stream.str();
+ repl.text = std::to_string(identifier.location.file);
}
}
}
@@ -270,15 +331,15 @@
assert(macro.type == Macro::kTypeFunc);
std::vector<MacroArg> args;
args.reserve(macro.parameters.size());
- if (!collectMacroArgs(macro, identifier, &args))
+ if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
return false;
replaceMacroParams(macro, args, replacements);
}
- for (size_t i = 0; i < replacements->size(); ++i)
+ for (std::size_t i = 0; i < replacements->size(); ++i)
{
- Token& repl = replacements->at(i);
+ Token &repl = replacements->at(i);
if (i == 0)
{
// The first token in the replacement list inherits the padding
@@ -286,34 +347,42 @@
repl.setAtStartOfLine(identifier.atStartOfLine());
repl.setHasLeadingSpace(identifier.hasLeadingSpace());
}
- repl.location = identifier.location;
+ repl.location = replacementLocation;
}
return true;
}
-bool MacroExpander::collectMacroArgs(const Macro& macro,
- const Token& identifier,
- std::vector<MacroArg>* args)
+bool MacroExpander::collectMacroArgs(const Macro ¯o,
+ const Token &identifier,
+ std::vector<MacroArg> *args,
+ SourceLocation *closingParenthesisLocation)
{
Token token;
getToken(&token);
assert(token.type == '(');
args->push_back(MacroArg());
- for (int openParens = 1; openParens != 0; )
+
+ // Defer reenabling macros until args collection is finished to avoid the possibility of
+ // infinite recursion. Otherwise infinite recursion might happen when expanding the args after
+ // macros have been popped from the context stack when parsing the args.
+ ScopedMacroReenabler deferReenablingMacros(this);
+
+ int openParens = 1;
+ while (openParens != 0)
{
getToken(&token);
if (token.type == Token::LAST)
{
- mDiagnostics->report(Diagnostics::MACRO_UNTERMINATED_INVOCATION,
- identifier.location, identifier.text);
+ mDiagnostics->report(Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION, identifier.location,
+ identifier.text);
// Do not lose EOF token.
ungetToken(token);
return false;
}
- bool isArg = false; // True if token is part of the current argument.
+ bool isArg = false; // True if token is part of the current argument.
switch (token.type)
{
case '(':
@@ -323,12 +392,14 @@
case ')':
--openParens;
isArg = openParens != 0;
+ *closingParenthesisLocation = token.location;
break;
case ',':
// The individual arguments are separated by comma tokens, but
// the comma tokens between matching inner parentheses do not
// seperate arguments.
- if (openParens == 1) args->push_back(MacroArg());
+ if (openParens == 1)
+ args->push_back(MacroArg());
isArg = openParens != 1;
break;
default:
@@ -337,14 +408,15 @@
}
if (isArg)
{
- MacroArg& arg = args->back();
+ MacroArg &arg = args->back();
// Initial whitespace is not part of the argument.
- if (arg.empty()) token.setHasLeadingSpace(false);
+ if (arg.empty())
+ token.setHasLeadingSpace(false);
arg.push_back(token);
}
}
- const Macro::Parameters& params = macro.parameters;
+ const Macro::Parameters ¶ms = macro.parameters;
// If there is only one empty argument, it is equivalent to no argument.
if (params.empty() && (args->size() == 1) && args->front().empty())
{
@@ -354,8 +426,8 @@
if (args->size() != params.size())
{
Diagnostics::ID id = args->size() < macro.parameters.size() ?
- Diagnostics::MACRO_TOO_FEW_ARGS :
- Diagnostics::MACRO_TOO_MANY_ARGS;
+ Diagnostics::PP_MACRO_TOO_FEW_ARGS :
+ Diagnostics::PP_MACRO_TOO_MANY_ARGS;
mDiagnostics->report(id, identifier.location, identifier.text);
return false;
}
@@ -363,11 +435,17 @@
// Pre-expand each argument before substitution.
// This step expands each argument individually before they are
// inserted into the macro body.
- for (size_t i = 0; i < args->size(); ++i)
+ size_t numTokens = 0;
+ for (auto &arg : *args)
{
- MacroArg& arg = args->at(i);
TokenLexer lexer(&arg);
- MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined);
+ if (mAllowedMacroExpansionDepth < 1)
+ {
+ mDiagnostics->report(Diagnostics::PP_MACRO_INVOCATION_CHAIN_TOO_DEEP,
+ token.location, token.text);
+ return false;
+ }
+ MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined, mAllowedMacroExpansionDepth - 1);
arg.clear();
expander.lex(&token);
@@ -375,18 +453,32 @@
{
arg.push_back(token);
expander.lex(&token);
+ numTokens++;
+ if (numTokens + mTotalTokensInContexts > kMaxContextTokens)
+ {
+ mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
+ return false;
+ }
}
}
return true;
}
-void MacroExpander::replaceMacroParams(const Macro& macro,
- const std::vector<MacroArg>& args,
- std::vector<Token>* replacements)
+void MacroExpander::replaceMacroParams(const Macro ¯o,
+ const std::vector<MacroArg> &args,
+ std::vector<Token> *replacements)
{
- for (size_t i = 0; i < macro.replacements.size(); ++i)
+ for (std::size_t i = 0; i < macro.replacements.size(); ++i)
{
- const Token& repl = macro.replacements[i];
+ if (!replacements->empty() &&
+ replacements->size() + mTotalTokensInContexts > kMaxContextTokens)
+ {
+ const Token &token = replacements->back();
+ mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text);
+ return;
+ }
+
+ const Token &repl = macro.replacements[i];
if (repl.type != Token::IDENTIFIER)
{
replacements->push_back(repl);
@@ -396,21 +488,21 @@
// TODO(alokp): Optimize this.
// There is no need to search for macro params every time.
// The param index can be cached with the replacement token.
- Macro::Parameters::const_iterator iter = std::find(
- macro.parameters.begin(), macro.parameters.end(), repl.text);
+ Macro::Parameters::const_iterator iter =
+ std::find(macro.parameters.begin(), macro.parameters.end(), repl.text);
if (iter == macro.parameters.end())
{
replacements->push_back(repl);
continue;
}
- size_t iArg = std::distance(macro.parameters.begin(), iter);
- const MacroArg& arg = args[iArg];
+ std::size_t iArg = std::distance(macro.parameters.begin(), iter);
+ const MacroArg &arg = args[iArg];
if (arg.empty())
{
continue;
}
- size_t iRepl = replacements->size();
+ std::size_t iRepl = replacements->size();
replacements->insert(replacements->end(), arg.begin(), arg.end());
// The replacement token inherits padding properties from
// macro replacement token.
@@ -418,5 +510,29 @@
}
}
+MacroExpander::MacroContext::MacroContext() : macro(0), index(0)
+{
+}
+
+MacroExpander::MacroContext::~MacroContext()
+{
+}
+
+bool MacroExpander::MacroContext::empty() const
+{
+ return index == replacements.size();
+}
+
+const Token &MacroExpander::MacroContext::get()
+{
+ return replacements[index++];
+}
+
+void MacroExpander::MacroContext::unget()
+{
+ assert(index > 0);
+ --index;
+}
+
} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/MacroExpander.h b/src/OpenGL/compiler/preprocessor/MacroExpander.h
index c8c3920..f7c1701 100644
--- a/src/OpenGL/compiler/preprocessor/MacroExpander.h
+++ b/src/OpenGL/compiler/preprocessor/MacroExpander.h
@@ -15,7 +15,6 @@
#ifndef COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
#define COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
-#include <cassert>
#include <memory>
#include <vector>
@@ -27,58 +26,67 @@
{
class Diagnostics;
+struct SourceLocation;
class MacroExpander : public Lexer
{
public:
- MacroExpander(Lexer* lexer, MacroSet* macroSet, Diagnostics* diagnostics, bool parseDefined);
- virtual ~MacroExpander();
+ MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics, bool parseDefined, int allowedMacroExpansionDepth);
+ ~MacroExpander() override;
- virtual void lex(Token* token);
+ void lex(Token *token) override;
private:
PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander);
- void getToken(Token* token);
- void ungetToken(const Token& token);
+ void getToken(Token *token);
+ void ungetToken(const Token &token);
bool isNextTokenLeftParen();
- bool pushMacro(const Macro& macro, const Token& identifier);
+ bool pushMacro(std::shared_ptr<Macro> macro, const Token &identifier);
void popMacro();
- bool expandMacro(const Macro& macro,
- const Token& identifier,
- std::vector<Token>* replacements);
+ bool expandMacro(const Macro ¯o, const Token &identifier, std::vector<Token> *replacements);
typedef std::vector<Token> MacroArg;
- bool collectMacroArgs(const Macro& macro,
- const Token& identifier,
- std::vector<MacroArg>* args);
- void replaceMacroParams(const Macro& macro,
- const std::vector<MacroArg>& args,
- std::vector<Token>* replacements);
+ bool collectMacroArgs(const Macro ¯o,
+ const Token &identifier,
+ std::vector<MacroArg> *args,
+ SourceLocation *closingParenthesisLocation);
+ void replaceMacroParams(const Macro ¯o,
+ const std::vector<MacroArg> &args,
+ std::vector<Token> *replacements);
struct MacroContext
{
- const Macro* macro;
- size_t index;
- std::vector<Token> replacements;
+ MacroContext();
+ ~MacroContext();
+ bool empty() const;
+ const Token &get();
+ void unget();
- MacroContext() : macro(0), index(0) { }
- bool empty() const { return index == replacements.size(); }
- const Token& get() { return replacements[index++]; }
- void unget() { assert(index > 0); --index; }
+ std::shared_ptr<Macro> macro;
+ std::size_t index;
+ std::vector<Token> replacements;
};
- Lexer* mLexer;
- MacroSet* mMacroSet;
- Diagnostics* mDiagnostics;
+ Lexer *mLexer;
+ MacroSet *mMacroSet;
+ Diagnostics *mDiagnostics;
const bool mParseDefined;
- Token* mReserveToken;
- std::vector<MacroContext*> mContextStack;
+ std::unique_ptr<Token> mReserveToken;
+ std::vector<MacroContext *> mContextStack;
+ size_t mTotalTokensInContexts;
+
+ int mAllowedMacroExpansionDepth;
+
+ bool mDeferReenablingMacros;
+ std::vector<std::shared_ptr<Macro>> mMacrosToReenable;
+
+ class ScopedMacroReenabler;
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
+#endif // COMPILER_PREPROCESSOR_MACROEXPANDER_H_
diff --git a/src/OpenGL/compiler/preprocessor/Preprocessor.cpp b/src/OpenGL/compiler/preprocessor/Preprocessor.cpp
index 4ce0bf4..e4e2b5e 100644
--- a/src/OpenGL/compiler/preprocessor/Preprocessor.cpp
+++ b/src/OpenGL/compiler/preprocessor/Preprocessor.cpp
@@ -15,9 +15,8 @@
#include "Preprocessor.h"
#include <cassert>
-#include <sstream>
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "DirectiveParser.h"
#include "Macro.h"
#include "MacroExpander.h"
@@ -29,25 +28,28 @@
struct PreprocessorImpl
{
- Diagnostics* diagnostics;
+ Diagnostics *diagnostics;
MacroSet macroSet;
Tokenizer tokenizer;
DirectiveParser directiveParser;
MacroExpander macroExpander;
- PreprocessorImpl(Diagnostics* diag, DirectiveHandler* directiveHandler) :
- diagnostics(diag),
- tokenizer(diag),
- directiveParser(&tokenizer, ¯oSet, diag, directiveHandler),
- macroExpander(&directiveParser, ¯oSet, diag, false)
+ PreprocessorImpl(Diagnostics *diag,
+ DirectiveHandler *directiveHandler,
+ const PreprocessorSettings &settings)
+ : diagnostics(diag),
+ tokenizer(diag),
+ directiveParser(&tokenizer, ¯oSet, diag, directiveHandler, settings.maxMacroExpansionDepth),
+ macroExpander(&directiveParser, ¯oSet, diag, false, settings.maxMacroExpansionDepth)
{
}
};
-Preprocessor::Preprocessor(Diagnostics* diagnostics,
- DirectiveHandler* directiveHandler)
+Preprocessor::Preprocessor(Diagnostics *diagnostics,
+ DirectiveHandler *directiveHandler,
+ const PreprocessorSettings &settings)
{
- mImpl = new PreprocessorImpl(diagnostics, directiveHandler);
+ mImpl = new PreprocessorImpl(diagnostics, directiveHandler, settings);
}
Preprocessor::~Preprocessor()
@@ -55,40 +57,25 @@
delete mImpl;
}
-bool Preprocessor::init(int count,
- const char* const string[],
- const int length[])
+bool Preprocessor::init(size_t count, const char *const string[], const int length[])
{
- static const int kGLSLVersion = 100;
+ static const int kDefaultGLSLVersion = 100;
// Add standard pre-defined macros.
predefineMacro("__LINE__", 0);
predefineMacro("__FILE__", 0);
- predefineMacro("__VERSION__", kGLSLVersion);
+ predefineMacro("__VERSION__", kDefaultGLSLVersion);
predefineMacro("GL_ES", 1);
return mImpl->tokenizer.init(count, string, length);
}
-void Preprocessor::predefineMacro(const char* name, int value)
+void Preprocessor::predefineMacro(const char *name, int value)
{
- std::ostringstream stream;
- stream << value;
-
- Token token;
- token.type = Token::CONST_INT;
- token.text = stream.str();
-
- Macro macro;
- macro.predefined = true;
- macro.type = Macro::kTypeObj;
- macro.name = name;
- macro.replacements.push_back(token);
-
- mImpl->macroSet[name] = macro;
+ PredefineMacro(&mImpl->macroSet, name, value);
}
-void Preprocessor::lex(Token* token)
+void Preprocessor::lex(Token *token)
{
bool validToken = false;
while (!validToken)
@@ -102,40 +89,12 @@
case Token::PP_HASH:
assert(false);
break;
- case Token::CONST_INT:
- {
- int val = 0;
- if (!token->iValue(&val))
- {
- // Do not mark the token as invalid.
- // Just emit the diagnostic and reset value to 0.
- mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,
- token->location, token->text);
- token->text.assign("0");
- }
- validToken = true;
- break;
- }
- case Token::CONST_FLOAT:
- {
- float val = 0;
- if (!token->fValue(&val))
- {
- // Do not mark the token as invalid.
- // Just emit the diagnostic and reset value to 0.0.
- mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,
- token->location, token->text);
- token->text.assign("0.0");
- }
- validToken = true;
- break;
- }
case Token::PP_NUMBER:
- mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
+ mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER,
token->location, token->text);
break;
case Token::PP_OTHER:
- mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
+ mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER,
token->location, token->text);
break;
default:
@@ -145,5 +104,9 @@
}
}
-} // namespace pp
+void Preprocessor::setMaxTokenSize(size_t maxTokenSize)
+{
+ mImpl->tokenizer.setMaxTokenSize(maxTokenSize);
+}
+} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/Preprocessor.h b/src/OpenGL/compiler/preprocessor/Preprocessor.h
index 62eca56..a8e139c 100644
--- a/src/OpenGL/compiler/preprocessor/Preprocessor.h
+++ b/src/OpenGL/compiler/preprocessor/Preprocessor.h
@@ -17,6 +17,8 @@
#include "pp_utils.h"
+#include <cstddef>
+
namespace pp
{
@@ -25,10 +27,18 @@
struct PreprocessorImpl;
struct Token;
+struct PreprocessorSettings
+{
+ PreprocessorSettings() : maxMacroExpansionDepth(1000) {}
+ int maxMacroExpansionDepth;
+};
+
class Preprocessor
{
public:
- Preprocessor(Diagnostics* diagnostics, DirectiveHandler* directiveHandler);
+ Preprocessor(Diagnostics *diagnostics,
+ DirectiveHandler *directiveHandler,
+ const PreprocessorSettings &settings);
~Preprocessor();
// count: specifies the number of elements in the string and length arrays.
@@ -40,16 +50,19 @@
// Each element in the length array may contain the length of the
// corresponding string or a value less than 0 to indicate that the string
// is null terminated.
- bool init(int count, const char* const string[], const int length[]);
+ bool init(size_t count, const char *const string[], const int length[]);
// Adds a pre-defined macro.
- void predefineMacro(const char* name, int value);
+ void predefineMacro(const char *name, int value);
- void lex(Token* token);
+ void lex(Token *token);
+
+ // Set maximum preprocessor token size
+ void setMaxTokenSize(size_t maxTokenSize);
private:
PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor);
- PreprocessorImpl* mImpl;
+ PreprocessorImpl *mImpl;
};
} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/SourceLocation.h b/src/OpenGL/compiler/preprocessor/SourceLocation.h
index b01e73b..234d304 100644
--- a/src/OpenGL/compiler/preprocessor/SourceLocation.h
+++ b/src/OpenGL/compiler/preprocessor/SourceLocation.h
@@ -20,10 +20,10 @@
struct SourceLocation
{
- SourceLocation() : file(0), line(0) { }
- SourceLocation(int f, int l) : file(f), line(l) { }
+ SourceLocation() : file(0), line(0) {}
+ SourceLocation(int f, int l) : file(f), line(l) {}
- bool equals(const SourceLocation& other) const
+ bool equals(const SourceLocation &other) const
{
return (file == other.file) && (line == other.line);
}
@@ -32,12 +32,12 @@
int line;
};
-inline bool operator==(const SourceLocation& lhs, const SourceLocation& rhs)
+inline bool operator==(const SourceLocation &lhs, const SourceLocation &rhs)
{
return lhs.equals(rhs);
}
-inline bool operator!=(const SourceLocation& lhs, const SourceLocation& rhs)
+inline bool operator!=(const SourceLocation &lhs, const SourceLocation &rhs)
{
return !lhs.equals(rhs);
}
diff --git a/src/OpenGL/compiler/preprocessor/Token.cpp b/src/OpenGL/compiler/preprocessor/Token.cpp
index 28d6f8c..731a592 100644
--- a/src/OpenGL/compiler/preprocessor/Token.cpp
+++ b/src/OpenGL/compiler/preprocessor/Token.cpp
@@ -29,7 +29,7 @@
text.clear();
}
-bool Token::equals(const Token& other) const
+bool Token::equals(const Token &other) const
{
return (type == other.type) &&
(flags == other.flags) &&
@@ -61,25 +61,25 @@
flags &= ~EXPANSION_DISABLED;
}
-bool Token::iValue(int* value) const
+bool Token::iValue(int *value) const
{
assert(type == CONST_INT);
return numeric_lex_int(text, value);
}
-bool Token::uValue(unsigned int* value) const
+bool Token::uValue(unsigned int *value) const
{
assert(type == CONST_INT);
return numeric_lex_int(text, value);
}
-bool Token::fValue(float* value) const
+bool Token::fValue(float *value) const
{
assert(type == CONST_FLOAT);
return numeric_lex_float(text, value);
}
-std::ostream& operator<<(std::ostream& out, const Token& token)
+std::ostream &operator<<(std::ostream &out, const Token &token)
{
if (token.hasLeadingSpace())
out << " ";
diff --git a/src/OpenGL/compiler/preprocessor/Token.h b/src/OpenGL/compiler/preprocessor/Token.h
index ddd3aac..c0475a8 100644
--- a/src/OpenGL/compiler/preprocessor/Token.h
+++ b/src/OpenGL/compiler/preprocessor/Token.h
@@ -27,6 +27,8 @@
{
enum Type
{
+ // Calling this ERROR causes a conflict with wingdi.h
+ GOT_ERROR = -1,
LAST = 0, // EOF.
IDENTIFIER = 258,
@@ -70,10 +72,10 @@
EXPANSION_DISABLED = 1 << 2
};
- Token() : type(0), flags(0) { }
+ Token() : type(0), flags(0) {}
void reset();
- bool equals(const Token& other) const;
+ bool equals(const Token &other) const;
// Returns true if this is the first token on line.
// It disregards any leading whitespace.
@@ -88,9 +90,9 @@
// Converts text into numeric value for CONST_INT and CONST_FLOAT token.
// Returns false if the parsed value cannot fit into an int or float.
- bool iValue(int* value) const;
- bool uValue(unsigned int* value) const;
- bool fValue(float* value) const;
+ bool iValue(int *value) const;
+ bool uValue(unsigned int *value) const;
+ bool fValue(float *value) const;
int type;
unsigned int flags;
@@ -98,17 +100,17 @@
std::string text;
};
-inline bool operator==(const Token& lhs, const Token& rhs)
+inline bool operator==(const Token &lhs, const Token &rhs)
{
return lhs.equals(rhs);
}
-inline bool operator!=(const Token& lhs, const Token& rhs)
+inline bool operator!=(const Token &lhs, const Token &rhs)
{
return !lhs.equals(rhs);
}
-extern std::ostream& operator<<(std::ostream& out, const Token& token);
+std::ostream &operator<<(std::ostream &out, const Token &token);
} // namepsace pp
#endif // COMPILER_PREPROCESSOR_TOKEN_H_
diff --git a/src/OpenGL/compiler/preprocessor/Tokenizer.cpp b/src/OpenGL/compiler/preprocessor/Tokenizer.cpp
index 13e93ce..44025a9 100644
--- a/src/OpenGL/compiler/preprocessor/Tokenizer.cpp
+++ b/src/OpenGL/compiler/preprocessor/Tokenizer.cpp
@@ -1,4 +1,4 @@
-#line 16 "./Tokenizer.l"
+#line 24 "./Tokenizer.l"
// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,20 +17,330 @@
-#line 13 "./Tokenizer.cpp"
-
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
+
+
+
+
+
+
+
+
+
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 0
+#define YY_FLEX_SUBMINOR_VERSION 4
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+#ifdef yy_create_buffer
+#define pp_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer pp_create_buffer
+#endif
+
+
+#ifdef yy_delete_buffer
+#define pp_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer pp_delete_buffer
+#endif
+
+
+#ifdef yy_scan_buffer
+#define pp_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer pp_scan_buffer
+#endif
+
+
+#ifdef yy_scan_string
+#define pp_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string pp_scan_string
+#endif
+
+
+#ifdef yy_scan_bytes
+#define pp_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes pp_scan_bytes
+#endif
+
+
+#ifdef yy_init_buffer
+#define pp_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer pp_init_buffer
+#endif
+
+
+#ifdef yy_flush_buffer
+#define pp_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer pp_flush_buffer
+#endif
+
+
+#ifdef yy_load_buffer_state
+#define pp_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state pp_load_buffer_state
+#endif
+
+
+#ifdef yy_switch_to_buffer
+#define pp_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer pp_switch_to_buffer
+#endif
+
+
+#ifdef yypush_buffer_state
+#define pppush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state pppush_buffer_state
+#endif
+
+
+#ifdef yypop_buffer_state
+#define pppop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state pppop_buffer_state
+#endif
+
+
+#ifdef yyensure_buffer_stack
+#define ppensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack ppensure_buffer_stack
+#endif
+
+
+#ifdef yylex
+#define pplex_ALREADY_DEFINED
+#else
+#define yylex pplex
+#endif
+
+
+#ifdef yyrestart
+#define pprestart_ALREADY_DEFINED
+#else
+#define yyrestart pprestart
+#endif
+
+
+#ifdef yylex_init
+#define pplex_init_ALREADY_DEFINED
+#else
+#define yylex_init pplex_init
+#endif
+
+
+#ifdef yylex_init_extra
+#define pplex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra pplex_init_extra
+#endif
+
+
+#ifdef yylex_destroy
+#define pplex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy pplex_destroy
+#endif
+
+
+#ifdef yyget_debug
+#define ppget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug ppget_debug
+#endif
+
+
+#ifdef yyset_debug
+#define ppset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug ppset_debug
+#endif
+
+
+#ifdef yyget_extra
+#define ppget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra ppget_extra
+#endif
+
+
+#ifdef yyset_extra
+#define ppset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra ppset_extra
+#endif
+
+
+#ifdef yyget_in
+#define ppget_in_ALREADY_DEFINED
+#else
+#define yyget_in ppget_in
+#endif
+
+
+#ifdef yyset_in
+#define ppset_in_ALREADY_DEFINED
+#else
+#define yyset_in ppset_in
+#endif
+
+
+#ifdef yyget_out
+#define ppget_out_ALREADY_DEFINED
+#else
+#define yyget_out ppget_out
+#endif
+
+
+#ifdef yyset_out
+#define ppset_out_ALREADY_DEFINED
+#else
+#define yyset_out ppset_out
+#endif
+
+
+#ifdef yyget_leng
+#define ppget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng ppget_leng
+#endif
+
+
+#ifdef yyget_text
+#define ppget_text_ALREADY_DEFINED
+#else
+#define yyget_text ppget_text
+#endif
+
+
+#ifdef yyget_lineno
+#define ppget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno ppget_lineno
+#endif
+
+
+#ifdef yyset_lineno
+#define ppset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno ppset_lineno
+#endif
+
+
+
+#ifdef yyget_column
+#define ppget_column_ALREADY_DEFINED
+#else
+#define yyget_column ppget_column
+#endif
+
+
+#ifdef yyset_column
+#define ppset_column_ALREADY_DEFINED
+#else
+#define yyset_column ppset_column
+#endif
+
+
+
+#ifdef yywrap
+#define ppwrap_ALREADY_DEFINED
+#else
+#define yywrap ppwrap
+#endif
+
+
+
+
+
+#ifdef yyget_lval
+#define ppget_lval_ALREADY_DEFINED
+#else
+#define yyget_lval ppget_lval
+#endif
+
+
+#ifdef yyset_lval
+#define ppset_lval_ALREADY_DEFINED
+#else
+#define yyset_lval ppset_lval
+#endif
+
+
+
+
+
+#ifdef yyget_lloc
+#define ppget_lloc_ALREADY_DEFINED
+#else
+#define yyget_lloc ppget_lloc
+#endif
+
+
+#ifdef yyset_lloc
+#define ppset_lloc_ALREADY_DEFINED
+#else
+#define yyset_lloc ppset_lloc
+#endif
+
+
+
+
+#ifdef yyalloc
+#define ppalloc_ALREADY_DEFINED
+#else
+#define yyalloc ppalloc
+#endif
+
+
+#ifdef yyrealloc
+#define pprealloc_ALREADY_DEFINED
+#else
+#define yyrealloc pprealloc
+#endif
+
+
+#ifdef yyfree
+#define ppfree_ALREADY_DEFINED
+#else
+#define yyfree ppfree
+#endif
+
+
+
+
+
+
+
+
+
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
@@ -101,40 +411,38 @@
#define UINT32_MAX (4294967295U)
#endif
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
-#ifdef __cplusplus
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
+/* begin standard C++ headers. */
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
#else
-#define yyconst
+#define yynoreturn
#endif
/* Returned upon end-of-file. */
#define YY_NULL 0
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
*/
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+
+
+
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -142,6 +450,22 @@
typedef void* yyscan_t;
#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/* For convenience, these vars (plus the bison vars far below)
are macros in the reentrant scanner. */
#define yyin yyg->yyin_r
@@ -153,27 +477,36 @@
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
#define yy_flex_debug yyg->yy_flex_debug_r
+
+
+
+
+
+
+
+
+
+
+
+
/* Enter a start condition. This macro really ought to take a parameter,
* but we do it the disgusting crufty way forced on us by the ()-less
* definition of BEGIN.
*/
#define BEGIN yyg->yy_start = 1 + 2 *
-
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
#define YY_START ((yyg->yy_start - 1) / 2)
#define YYSTATE YY_START
-
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE pprestart(yyin ,yyscanner )
-
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
#define YY_END_OF_BUFFER_CHAR 0
+
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
#ifdef __ia64__
@@ -187,10 +520,13 @@
#endif /* __ia64__ */
#endif
+
/* The state buf must be large enough to hold one state per character in the main buffer.
*/
#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
@@ -201,10 +537,13 @@
typedef size_t yy_size_t;
#endif
+
+
+
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
-
+
#define YY_LESS_LINENO(n)
#define YY_LINENO_REWIND_TO(ptr)
@@ -221,27 +560,29 @@
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
-
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
FILE *yy_input_file;
+
+
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
- yy_size_t yy_buf_size;
+ int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- yy_size_t yy_n_chars;
+ int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -264,7 +605,8 @@
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -281,7 +623,7 @@
* possible backing-up.
*
* When we actually see the EOF, we change the status to "new"
- * (via pprestart()), so that the user can continue scanning by
+ * (via yyrestart()), so that the user can continue scanning by
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
@@ -289,6 +631,9 @@
};
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+
+
/* We provide macros for accessing buffer states in case in the
* future we want to put the buffer states in a more general
* "scanner state".
@@ -298,89 +643,97 @@
#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
: NULL)
-
/* Same as previous macro, but useful when we know that the buffer stack is not
* NULL or when we need an lvalue. For internal use only.
*/
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-void pprestart (FILE *input_file ,yyscan_t yyscanner );
-void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE pp_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void pp_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void pp_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void pppush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void pppop_buffer_state (yyscan_t yyscanner );
-static void ppensure_buffer_stack (yyscan_t yyscanner );
-static void pp_load_buffer_state (yyscan_t yyscanner );
-static void pp_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER pp_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-YY_BUFFER_STATE pp_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE pp_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
-void *ppalloc (yy_size_t ,yyscan_t yyscanner );
-void *pprealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void ppfree (void * ,yyscan_t yyscanner );
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
-#define yy_new_buffer pp_create_buffer
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
+
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+
+
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
+
+
+#define yy_new_buffer yy_create_buffer
#define yy_set_interactive(is_interactive) \
{ \
if ( ! YY_CURRENT_BUFFER ){ \
- ppensure_buffer_stack (yyscanner); \
+ yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
-
#define yy_set_bol(at_bol) \
{ \
if ( ! YY_CURRENT_BUFFER ){\
- ppensure_buffer_stack (yyscanner); \
+ yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
-
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
/* Begin user sect3 */
#define ppwrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
+typedef flex_uint8_t YY_CHAR;
-typedef unsigned char YY_CHAR;
typedef int yy_state_type;
#define yytext_ptr yytext_r
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-#if defined(__GNUC__) && __GNUC__ >= 3
-__attribute__((__noreturn__))
-#endif
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+
+
+
+
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
+
+
+
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
+ yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 38
-#define YY_END_OF_BUFFER 39
+#define YY_NUM_RULES 37
+#define YY_END_OF_BUFFER 38
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -388,22 +741,22 @@
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[98] =
+static const flex_int16_t yy_accept[95] =
{ 0,
- 0, 0, 0, 0, 39, 37, 34, 35, 35, 33,
+ 0, 0, 0, 0, 38, 36, 34, 35, 35, 33,
7, 33, 33, 33, 33, 33, 33, 33, 33, 9,
- 9, 33, 33, 33, 8, 37, 33, 33, 3, 5,
- 5, 4, 34, 35, 19, 27, 20, 30, 25, 12,
- 23, 13, 24, 10, 2, 1, 26, 10, 9, 11,
- 11, 11, 9, 11, 9, 9, 14, 16, 18, 17,
- 15, 8, 36, 36, 31, 21, 32, 22, 3, 5,
- 6, 11, 10, 11, 10, 1, 10, 11, 10, 0,
- 10, 9, 9, 9, 28, 29, 0, 10, 10, 10,
- 10, 9, 10, 10, 9, 10, 0
+ 9, 33, 33, 33, 8, 33, 33, 3, 5, 5,
+ 4, 34, 35, 19, 27, 20, 30, 25, 12, 23,
+ 13, 24, 10, 2, 1, 26, 10, 9, 11, 11,
+ 11, 9, 11, 9, 9, 14, 16, 18, 17, 15,
+ 8, 31, 21, 32, 22, 3, 5, 6, 11, 10,
+ 11, 10, 1, 10, 11, 10, 0, 10, 9, 9,
+ 9, 28, 29, 0, 10, 10, 10, 10, 9, 10,
+ 10, 9, 10, 0
} ;
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
2, 2, 4, 1, 1, 1, 1, 1, 1, 1,
@@ -414,11 +767,11 @@
19, 20, 9, 1, 21, 21, 21, 21, 22, 23,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 25, 24, 24, 26, 24, 24,
- 9, 27, 9, 28, 24, 1, 21, 21, 21, 21,
+ 9, 1, 9, 27, 24, 1, 21, 21, 21, 21,
22, 23, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 25, 24, 24, 26,
- 24, 24, 9, 29, 9, 9, 1, 1, 1, 1,
+ 24, 24, 9, 28, 9, 9, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -435,101 +788,99 @@
1, 1, 1, 1, 1
} ;
-static yyconst YY_CHAR yy_meta[30] =
+static const YY_CHAR yy_meta[29] =
{ 0,
1, 1, 2, 2, 1, 1, 1, 1, 1, 3,
1, 1, 4, 1, 5, 5, 5, 1, 1, 1,
- 5, 5, 5, 5, 5, 5, 1, 1, 1
+ 5, 5, 5, 5, 5, 5, 1, 1
} ;
-static yyconst flex_uint16_t yy_base[103] =
+static const flex_int16_t yy_base[100] =
{ 0,
- 0, 0, 27, 29, 137, 194, 133, 194, 117, 100,
- 194, 98, 26, 194, 94, 24, 28, 33, 32, 39,
- 51, 39, 80, 50, 0, 68, 25, 54, 0, 194,
- 88, 71, 80, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 71, 194, 0, 194, 85, 55, 64,
- 99, 111, 53, 105, 0, 50, 55, 194, 194, 194,
- 40, 0, 194, 38, 194, 194, 194, 194, 0, 194,
- 194, 117, 0, 130, 0, 0, 0, 137, 0, 88,
- 113, 0, 131, 0, 194, 194, 143, 139, 152, 150,
- 0, 13, 153, 194, 0, 194, 194, 176, 31, 181,
+ 0, 0, 26, 28, 133, 195, 130, 195, 128, 105,
+ 195, 104, 25, 195, 100, 23, 27, 32, 31, 38,
+ 50, 38, 93, 49, 0, 16, 51, 0, 195, 105,
+ 87, 93, 195, 195, 195, 195, 195, 195, 195, 195,
+ 195, 195, 67, 195, 0, 195, 81, 55, 84, 98,
+ 110, 53, 61, 0, 52, 39, 195, 195, 195, 33,
+ 0, 195, 195, 195, 195, 0, 195, 195, 113, 0,
+ 126, 0, 0, 0, 133, 0, 56, 128, 0, 133,
+ 0, 195, 195, 101, 141, 143, 145, 0, 15, 154,
+ 195, 0, 195, 195, 177, 32, 182, 187, 189
- 186, 188
} ;
-static yyconst flex_int16_t yy_def[103] =
+static const flex_int16_t yy_def[100] =
{ 0,
- 97, 1, 98, 98, 97, 97, 97, 97, 97, 97,
- 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
- 20, 97, 97, 97, 99, 97, 97, 97, 100, 97,
- 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 97, 97, 97, 101, 97, 97, 20, 20,
- 50, 51, 51, 102, 21, 51, 97, 97, 97, 97,
- 97, 99, 97, 97, 97, 97, 97, 97, 100, 97,
- 97, 44, 44, 72, 72, 101, 48, 51, 51, 97,
- 52, 51, 102, 51, 97, 97, 97, 74, 78, 97,
- 51, 51, 97, 97, 51, 97, 0, 97, 97, 97,
+ 94, 1, 95, 95, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 20, 94, 94, 94, 96, 94, 94, 97, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 98, 94, 94, 20, 20, 49,
+ 50, 50, 99, 21, 50, 94, 94, 94, 94, 94,
+ 96, 94, 94, 94, 94, 97, 94, 94, 43, 43,
+ 69, 69, 98, 47, 50, 50, 94, 51, 50, 99,
+ 50, 94, 94, 94, 71, 75, 94, 50, 50, 94,
+ 94, 50, 94, 0, 94, 94, 94, 94, 94
- 97, 97
} ;
-static yyconst flex_uint16_t yy_nxt[224] =
+static const flex_int16_t yy_nxt[224] =
{ 0,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 21, 22, 23, 24,
- 25, 25, 25, 25, 25, 25, 26, 27, 28, 30,
- 31, 30, 31, 37, 40, 62, 32, 95, 32, 42,
- 63, 45, 41, 65, 38, 46, 43, 44, 44, 44,
- 47, 48, 66, 49, 49, 50, 57, 58, 86, 51,
- 52, 51, 51, 53, 54, 55, 55, 55, 60, 61,
- 63, 64, 67, 85, 84, 56, 51, 82, 50, 50,
- 51, 33, 68, 72, 71, 73, 73, 73, 51, 51,
- 70, 72, 74, 75, 72, 72, 72, 51, 59, 77,
+ 25, 25, 25, 25, 25, 25, 26, 27, 29, 30,
+ 29, 30, 36, 39, 62, 31, 61, 31, 41, 92,
+ 44, 40, 63, 37, 45, 42, 43, 43, 43, 46,
+ 47, 83, 48, 48, 49, 56, 57, 82, 50, 51,
+ 50, 50, 52, 53, 54, 54, 54, 59, 60, 64,
+ 87, 87, 87, 50, 55, 50, 81, 79, 65, 69,
+ 50, 70, 70, 70, 50, 50, 50, 69, 71, 72,
+ 69, 69, 69, 50, 32, 74, 74, 74, 49, 49,
- 77, 77, 90, 90, 90, 51, 78, 79, 51, 51,
- 51, 51, 39, 51, 51, 51, 36, 51, 35, 34,
- 51, 80, 80, 97, 97, 81, 81, 81, 51, 51,
- 51, 72, 72, 72, 33, 91, 97, 97, 72, 72,
- 87, 87, 97, 51, 88, 88, 88, 87, 87, 97,
- 97, 89, 89, 89, 51, 92, 51, 93, 93, 93,
- 97, 75, 97, 97, 90, 90, 90, 93, 93, 93,
- 97, 97, 94, 97, 79, 96, 29, 29, 29, 29,
- 29, 69, 97, 97, 69, 69, 76, 97, 76, 76,
- 76, 83, 83, 5, 97, 97, 97, 97, 97, 97,
+ 68, 50, 75, 76, 50, 50, 50, 67, 50, 50,
+ 50, 58, 50, 50, 50, 90, 90, 90, 38, 50,
+ 77, 77, 35, 34, 78, 78, 78, 69, 69, 69,
+ 33, 32, 94, 94, 69, 69, 84, 84, 94, 94,
+ 85, 85, 85, 84, 84, 50, 94, 86, 86, 86,
+ 88, 94, 94, 94, 94, 94, 50, 89, 50, 87,
+ 87, 87, 94, 72, 94, 76, 94, 91, 90, 90,
+ 90, 94, 94, 94, 94, 94, 93, 28, 28, 28,
+ 28, 28, 66, 94, 94, 66, 66, 73, 94, 73,
+ 73, 73, 80, 80, 5, 94, 94, 94, 94, 94,
- 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 97
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94
} ;
-static yyconst flex_int16_t yy_chk[224] =
+static const flex_int16_t yy_chk[224] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
- 3, 4, 4, 13, 16, 99, 3, 92, 4, 17,
- 64, 19, 16, 27, 13, 19, 17, 18, 18, 18,
- 19, 20, 27, 20, 20, 20, 22, 22, 61, 20,
- 20, 20, 20, 20, 20, 21, 21, 21, 24, 24,
- 26, 26, 28, 57, 56, 21, 21, 53, 50, 50,
- 49, 33, 28, 44, 32, 44, 44, 44, 50, 50,
- 31, 44, 44, 44, 44, 44, 44, 48, 23, 48,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 4, 4, 13, 16, 26, 3, 96, 4, 17, 89,
+ 19, 16, 26, 13, 19, 17, 18, 18, 18, 19,
+ 20, 60, 20, 20, 20, 22, 22, 56, 20, 20,
+ 20, 20, 20, 20, 21, 21, 21, 24, 24, 27,
+ 77, 77, 77, 53, 21, 21, 55, 52, 27, 43,
+ 48, 43, 43, 43, 53, 53, 53, 43, 43, 43,
+ 43, 43, 43, 47, 32, 47, 47, 47, 49, 49,
- 48, 48, 80, 80, 80, 48, 48, 48, 48, 48,
- 48, 51, 15, 51, 51, 51, 12, 54, 10, 9,
- 51, 52, 52, 81, 81, 52, 52, 52, 54, 54,
- 54, 72, 72, 72, 7, 81, 5, 0, 72, 72,
- 74, 74, 0, 83, 74, 74, 74, 78, 78, 88,
- 88, 78, 78, 78, 83, 83, 83, 87, 87, 87,
- 0, 88, 89, 89, 90, 90, 90, 93, 93, 93,
- 0, 0, 90, 0, 89, 93, 98, 98, 98, 98,
- 98, 100, 0, 0, 100, 100, 101, 0, 101, 101,
- 101, 102, 102, 97, 97, 97, 97, 97, 97, 97,
+ 31, 47, 47, 47, 47, 47, 47, 30, 49, 49,
+ 50, 23, 50, 50, 50, 84, 84, 84, 15, 50,
+ 51, 51, 12, 10, 51, 51, 51, 69, 69, 69,
+ 9, 7, 5, 0, 69, 69, 71, 71, 78, 78,
+ 71, 71, 71, 75, 75, 80, 0, 75, 75, 75,
+ 78, 85, 85, 86, 86, 0, 80, 80, 80, 87,
+ 87, 87, 0, 85, 0, 86, 0, 87, 90, 90,
+ 90, 0, 0, 0, 0, 0, 90, 95, 95, 95,
+ 95, 95, 97, 0, 0, 97, 97, 98, 0, 98,
+ 98, 98, 99, 99, 94, 94, 94, 94, 94, 94,
- 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 97
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94
} ;
/* The intent behind this definition is that it'll catch
@@ -561,14 +912,27 @@
IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
*/
+#if defined(_MSC_VER)
+#pragma warning(disable: 4005)
+#endif
+
#include "Tokenizer.h"
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "Token.h"
#if defined(__GNUC__)
// Triggered by the auto-generated yy_fatal_error function.
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
+#elif defined(_MSC_VER)
+#pragma warning(disable: 4244)
+#endif
+
+// Workaround for flex using the register keyword, deprecated in C++11.
+#ifdef __cplusplus
+#if __cplusplus > 199711L
+#define register
+#endif
#endif
typedef std::string YYSTYPE;
@@ -602,13 +966,25 @@
} while(0);
#define YY_INPUT(buf, result, maxSize) \
- result = yyextra->input.read(buf, maxSize);
+ result = yyextra->input.read(buf, maxSize, &yylineno);
+
+
+
+
#define INITIAL 0
#define COMMENT 1
+
+
+
+
+
#define YY_EXTRA_TYPE pp::Tokenizer::Context*
+
+
+
/* Holds the entire state of the reentrant scanner. */
struct yyguts_t
{
@@ -622,8 +998,8 @@
size_t yy_buffer_stack_max; /**< capacity of stack. */
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
- yy_size_t yy_n_chars;
- yy_size_t yyleng_r;
+ int yy_n_chars;
+ int yyleng_r;
char *yy_c_buf_p;
int yy_init;
int yy_start;
@@ -637,78 +1013,141 @@
int yylineno_r;
int yy_flex_debug_r;
+
+
+
char *yytext_r;
int yy_more_flag;
int yy_more_len;
+
+
YYSTYPE * yylval_r;
+
+
YYLTYPE * yylloc_r;
+
}; /* end struct yyguts_t */
-static int yy_init_globals (yyscan_t yyscanner );
+
+
+static int yy_init_globals ( yyscan_t yyscanner );
+
+
+
+
+
/* This must go here because YYSTYPE and YYLTYPE are included
* from bison output in section 1.*/
# define yylval yyg->yylval_r
+
+
# define yylloc yyg->yylloc_r
-int pplex_init (yyscan_t* scanner);
-int pplex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+
+
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int pplex_destroy (yyscan_t yyscanner );
-int ppget_debug (yyscan_t yyscanner );
+int yylex_destroy ( yyscan_t yyscanner );
-void ppset_debug (int debug_flag ,yyscan_t yyscanner );
-YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner );
-void ppset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+int yyget_debug ( yyscan_t yyscanner );
-FILE *ppget_in (yyscan_t yyscanner );
-void ppset_in (FILE * _in_str ,yyscan_t yyscanner );
-FILE *ppget_out (yyscan_t yyscanner );
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
-void ppset_out (FILE * _out_str ,yyscan_t yyscanner );
-yy_size_t ppget_leng (yyscan_t yyscanner );
-char *ppget_text (yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
-int ppget_lineno (yyscan_t yyscanner );
-void ppset_lineno (int _line_number ,yyscan_t yyscanner );
-int ppget_column (yyscan_t yyscanner );
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
-void ppset_column (int _column_no ,yyscan_t yyscanner );
-YYSTYPE * ppget_lval (yyscan_t yyscanner );
-void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+FILE *yyget_in ( yyscan_t yyscanner );
- YYLTYPE *ppget_lloc (yyscan_t yyscanner );
+
+
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
+
+
+
+FILE *yyget_out ( yyscan_t yyscanner );
+
+
+
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
+
+
+
+ int yyget_leng ( yyscan_t yyscanner );
+
+
+
+char *yyget_text ( yyscan_t yyscanner );
+
+
+
+int yyget_lineno ( yyscan_t yyscanner );
+
+
+
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
+
+
+
+
+int yyget_column ( yyscan_t yyscanner );
+
+
+
+
+
+void yyset_column ( int _column_no , yyscan_t yyscanner );
+
+
+
+
+YYSTYPE * yyget_lval ( yyscan_t yyscanner );
+
+
+void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
+
+
- void ppset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+ YYLTYPE *yyget_lloc ( yyscan_t yyscanner );
+
+
+ void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner );
+
+
+
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int ppwrap (yyscan_t yyscanner );
+extern "C" int yywrap ( yyscan_t yyscanner );
#else
-extern int ppwrap (yyscan_t yyscanner );
+extern int yywrap ( yyscan_t yyscanner );
#endif
#endif
@@ -716,24 +1155,31 @@
#endif
+
#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
-
#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
+static int yyinput ( yyscan_t yyscanner );
#else
-static int input (yyscan_t yyscanner );
+static int input ( yyscan_t yyscanner );
#endif
#endif
+
+
+
+
+
+
+
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#ifdef __ia64__
@@ -744,14 +1190,17 @@
#endif /* __ia64__ */
#endif
+
/* Copy whatever the last rule matched to the standard output. */
#ifndef ECHO
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
#endif
+
+
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
* is returned in "result".
*/
@@ -760,7 +1209,7 @@
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- size_t n; \
+ int n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -773,7 +1222,7 @@
else \
{ \
errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
@@ -788,6 +1237,8 @@
#endif
+
+
/* No semi-colon after return; correct usage is to write "yyterminate();" -
* we don't want an extra ';' after the "return" because that will cause
* some compilers to complain about unreachable statements.
@@ -796,31 +1247,54 @@
#define yyterminate() return YY_NULL
#endif
+
/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif
+
/* Report a fatal error. */
#ifndef YY_FATAL_ERROR
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
#endif
+
+
/* end tables serialization structures and prototypes */
+
+
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
-extern int pplex \
- (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
-#define YY_DECL int pplex \
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+extern int yylex \
+ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner);
+
+#define YY_DECL int yylex \
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
#endif /* !YY_DECL */
+
/* Code executed at the beginning of each rule, after yytext and yyleng
* have been set up.
*/
@@ -828,14 +1302,19 @@
#define YY_USER_ACTION
#endif
+
+
/* Code executed at the end of each rule. */
#ifndef YY_BREAK
#define YY_BREAK /*LINTED*/break;
#endif
+
+
#define YY_RULE_SETUP \
YY_USER_ACTION
+
/** The main scanner function which does all the work.
*/
YY_DECL
@@ -845,10 +1324,16 @@
int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+
+
yylval = yylval_param;
+
+
yylloc = yylloc_param;
+
if ( !yyg->yy_init )
{
yyg->yy_init = 1;
@@ -857,6 +1342,8 @@
YY_USER_INIT;
#endif
+
+
if ( ! yyg->yy_start )
yyg->yy_start = 1; /* first start state */
@@ -867,16 +1354,17 @@
yyout = stdout;
if ( ! YY_CURRENT_BUFFER ) {
- ppensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- pp_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
{
+
/* Line comment */
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
@@ -904,13 +1392,13 @@
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 98 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ if ( yy_current_state >= 95 )
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
- while ( yy_current_state != 97 );
+ while ( yy_current_state != 94 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
@@ -919,8 +1407,11 @@
YY_DO_BEFORE_ACTION;
+
+
do_action: /* This label is used only to access EOF actions. */
+
switch ( yy_act )
{ /* beginning of action switch */
case 0: /* must back up */
@@ -936,7 +1427,7 @@
YY_BREAK
/* Block comment */
/* Line breaks are just counted - not returned. */
-/* The comment is replaced by a single space. */
+/* The comment is replaced by a single space. */
case 2:
YY_RULE_SETUP
{ BEGIN(COMMENT); }
@@ -952,7 +1443,14 @@
case 5:
/* rule 5 can match eol */
YY_RULE_SETUP
-{ ++yylineno; }
+{
+ if (yylineno == INT_MAX)
+ {
+ *yylval = "Integer overflow on line number";
+ return pp::Token::GOT_ERROR;
+ }
+ ++yylineno;
+}
YY_BREAK
case 6:
YY_RULE_SETUP
@@ -1161,17 +1659,17 @@
/* rule 35 can match eol */
YY_RULE_SETUP
{
+ if (yylineno == INT_MAX)
+ {
+ *yylval = "Integer overflow on line number";
+ return pp::Token::GOT_ERROR;
+ }
++yylineno;
yylval->assign(1, '\n');
return '\n';
}
YY_BREAK
case 36:
-/* rule 36 can match eol */
-YY_RULE_SETUP
-{ ++yylineno; }
- YY_BREAK
-case 37:
YY_RULE_SETUP
{
yylval->assign(1, yytext[0]);
@@ -1185,28 +1683,35 @@
// Set the location for EOF token manually.
pp::Input* input = &yyextra->input;
pp::Input::Location* scanLoc = &yyextra->scanLoc;
- int sIndexMax = std::max(0, input->count() - 1);
+ yy_size_t sIndexMax = input->count() ? input->count() - 1 : 0;
if (scanLoc->sIndex != sIndexMax)
{
// We can only reach here if there are empty strings at the
// end of the input.
scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
- yyfileno = sIndexMax; yylineno = 1;
+ // FIXME: this is not 64-bit clean.
+ yyfileno = static_cast<int>(sIndexMax); yylineno = 1;
}
yylloc->file = yyfileno;
yylloc->line = yylineno;
yylval->clear();
- if (YY_START == COMMENT)
+ // Line number overflows fake EOFs to exit early, check for this case.
+ if (yylineno == INT_MAX) {
+ yyextra->diagnostics->report(pp::Diagnostics::PP_TOKENIZER_ERROR,
+ pp::SourceLocation(yyfileno, yylineno),
+ "Integer overflow on line number");
+ }
+ else if (YY_START == COMMENT)
{
- yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT,
+ yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT,
pp::SourceLocation(yyfileno, yylineno),
- "");
+ "EOF while in a comment");
}
yyterminate();
}
YY_BREAK
-case 38:
+case 37:
YY_RULE_SETUP
ECHO;
YY_BREAK
@@ -1225,7 +1730,7 @@
/* We're scanning a new file or input source. It's
* possible that this happened because the user
* just pointed yyin at a new source and called
- * pplex(). If so, then we have to assure
+ * yylex(). If so, then we have to assure
* consistency between YY_CURRENT_BUFFER and our
* globals. Here is the right place to do so, because
* this is the first action (other than possibly a
@@ -1286,7 +1791,7 @@
{
yyg->yy_did_buffer_switch_on_eof = 0;
- if ( ppwrap(yyscanner ) )
+ if ( yywrap( yyscanner ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
@@ -1340,7 +1845,11 @@
} /* end of action switch */
} /* end of scanning one token */
} /* end of user's declarations */
-} /* end of pplex */
+} /* end of yylex */
+
+
+
+
/* yy_get_next_buffer - try to read in a new buffer
*
@@ -1354,7 +1863,7 @@
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = yyg->yytext_ptr;
- yy_size_t number_to_move, i;
+ int number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1383,7 +1892,7 @@
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -1396,7 +1905,7 @@
else
{
- yy_size_t num_to_read =
+ int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -1410,7 +1919,7 @@
if ( b->yy_is_our_buffer )
{
- yy_size_t new_size = b->yy_buf_size * 2;
+ int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@@ -1419,11 +1928,12 @@
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
- pprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
+ b->yy_ch_buf = NULL;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
@@ -1451,7 +1961,7 @@
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- pprestart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
}
else
@@ -1465,12 +1975,15 @@
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
}
yyg->yy_n_chars += number_to_move;
@@ -1482,6 +1995,7 @@
return ret_val;
}
+
/* yy_get_previous_state - get the state just before the EOB char was reached */
static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
@@ -1503,15 +2017,16 @@
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 98 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ if ( yy_current_state >= 95 )
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
}
return yy_current_state;
}
+
/* yy_try_NUL_trans - try to make a transition on the NUL character
*
* synopsis
@@ -1532,16 +2047,17 @@
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 98 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ if ( yy_current_state >= 95 )
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 97);
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 94);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state;
}
+
#ifndef YY_NO_UNPUT
#endif
@@ -1571,7 +2087,7 @@
else
{ /* need more input */
- yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -1588,14 +2104,14 @@
*/
/* Reset buffer status. */
- pprestart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
/*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( ppwrap(yyscanner ) )
- return EOF;
+ if ( yywrap( yyscanner ) )
+ return 0;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
@@ -1617,6 +2133,7 @@
*yyg->yy_c_buf_p = '\0'; /* preserve yytext */
yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
return c;
}
#endif /* ifndef YY_NO_INPUT */
@@ -1626,34 +2143,35 @@
* @param yyscanner The scanner object.
* @note This function does not reset the start condition to @c INITIAL .
*/
- void pprestart (FILE * input_file , yyscan_t yyscanner)
+ void yyrestart (FILE * input_file , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( ! YY_CURRENT_BUFFER ){
- ppensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- pp_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- pp_load_buffer_state(yyscanner );
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
+ yy_load_buffer_state( yyscanner );
}
+
/** Switch to a different input buffer.
* @param new_buffer The new input buffer.
* @param yyscanner The scanner object.
*/
- void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* TODO. We should be able to replace this entire function body
* with
- * pppop_buffer_state();
- * pppush_buffer_state(new_buffer);
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
*/
- ppensure_buffer_stack (yyscanner);
+ yyensure_buffer_stack (yyscanner);
if ( YY_CURRENT_BUFFER == new_buffer )
return;
@@ -1666,17 +2184,18 @@
}
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- pp_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
/* We don't actually know whether we did this switch during
- * EOF (ppwrap()) processing, but the only time this flag
- * is looked at is after ppwrap() is called, so it's safe
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
* to go ahead and always set it.
*/
yyg->yy_did_buffer_switch_on_eof = 1;
}
-static void pp_load_buffer_state (yyscan_t yyscanner)
+
+static void yy_load_buffer_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
@@ -1691,35 +2210,36 @@
* @param yyscanner The scanner object.
* @return the allocated buffer state.
*/
- YY_BUFFER_STATE pp_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
- b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
- b->yy_buf_size = (yy_size_t)size;
+ b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) ppalloc(b->yy_buf_size + 2 ,yyscanner );
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- pp_init_buffer(b,file ,yyscanner);
+ yy_init_buffer( b, file , yyscanner);
return b;
}
+
/** Destroy the buffer.
- * @param b a buffer created with pp_create_buffer()
+ * @param b a buffer created with yy_create_buffer()
* @param yyscanner The scanner object.
*/
- void pp_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -1730,28 +2250,29 @@
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- ppfree((void *) b->yy_ch_buf ,yyscanner );
+ yyfree( (void *) b->yy_ch_buf , yyscanner );
- ppfree((void *) b ,yyscanner );
+ yyfree( (void *) b , yyscanner );
}
+
/* Initializes or reinitializes a buffer.
* This function is sometimes called more than once on the same buffer,
- * such as during a pprestart() or at EOF.
+ * such as during a yyrestart() or at EOF.
*/
- static void pp_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
{
int oerrno = errno;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- pp_flush_buffer(b ,yyscanner);
+ yy_flush_buffer( b , yyscanner);
b->yy_input_file = file;
b->yy_fill_buffer = 1;
- /* If b is the current buffer, then pp_init_buffer was _probably_
- * called from pprestart() or through yy_get_next_buffer.
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
* In that case, we don't want to reset the lineno or column.
*/
if (b != YY_CURRENT_BUFFER){
@@ -1759,8 +2280,11 @@
b->yy_bs_column = 0;
}
+
+
b->yy_is_interactive = 0;
+
errno = oerrno;
}
@@ -1768,7 +2292,7 @@
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
* @param yyscanner The scanner object.
*/
- void pp_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if ( ! b )
@@ -1789,7 +2313,7 @@
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == YY_CURRENT_BUFFER )
- pp_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
/** Pushes the new state onto the stack. The new state becomes
@@ -1798,15 +2322,15 @@
* @param new_buffer The new state.
* @param yyscanner The scanner object.
*/
-void pppush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (new_buffer == NULL)
return;
- ppensure_buffer_stack(yyscanner);
+ yyensure_buffer_stack(yyscanner);
- /* This block is copied from pp_switch_to_buffer. */
+ /* This block is copied from yy_switch_to_buffer. */
if ( YY_CURRENT_BUFFER )
{
/* Flush out information for old buffer. */
@@ -1820,36 +2344,38 @@
yyg->yy_buffer_stack_top++;
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- /* copied from pp_switch_to_buffer. */
- pp_load_buffer_state(yyscanner );
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
+
/** Removes and deletes the top of the stack, if present.
* The next element becomes the new top.
* @param yyscanner The scanner object.
*/
-void pppop_buffer_state (yyscan_t yyscanner)
+void yypop_buffer_state (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
if (!YY_CURRENT_BUFFER)
return;
- pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
YY_CURRENT_BUFFER_LVALUE = NULL;
if (yyg->yy_buffer_stack_top > 0)
--yyg->yy_buffer_stack_top;
if (YY_CURRENT_BUFFER) {
- pp_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
}
+
/* Allocates the stack if it does not exist.
* Guarantees space for at least one push.
*/
-static void ppensure_buffer_stack (yyscan_t yyscanner)
+static void yyensure_buffer_stack (yyscan_t yyscanner)
{
yy_size_t num_to_alloc;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -1860,15 +2386,16 @@
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1; // After all that talk, this was set to 1 anyways...
- yyg->yy_buffer_stack = (struct yy_buffer_state**)ppalloc
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" );
-
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
yyg->yy_buffer_stack_max = num_to_alloc;
yyg->yy_buffer_stack_top = 0;
return;
@@ -1880,12 +2407,12 @@
yy_size_t grow_size = 8 /* arbitrary grow size */;
num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)pprealloc
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
(yyg->yy_buffer_stack,
num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
/* zero only the new slots.*/
memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -1893,13 +2420,17 @@
}
}
+
+
+
+
/** Setup the input buffer state to scan directly from a user-specified character buffer.
* @param base the character buffer
* @param size the size in bytes of the character buffer
* @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
@@ -1907,69 +2438,75 @@
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
- return 0;
+ return NULL;
- b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
+ b->yy_input_file = NULL;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- pp_switch_to_buffer(b ,yyscanner );
+ yy_switch_to_buffer( b , yyscanner );
return b;
}
-/** Setup the input buffer state to scan a string. The next call to pplex() will
+
+
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
* scan from a @e copy of @a str.
* @param yystr a NUL-terminated string to scan
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
- * pp_scan_bytes() instead.
+ * yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
{
- return pp_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
}
-/** Setup the input buffer state to scan the given bytes. The next call to pplex() will
+
+
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
* scan from a @e copy of @a bytes.
* @param yybytes the byte buffer to scan
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) ppalloc(n ,yyscanner );
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n , yyscanner );
if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" );
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
for ( i = 0; i < _yybytes_len; ++i )
buf[i] = yybytes[i];
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = pp_scan_buffer(buf,n ,yyscanner);
+ b = yy_scan_buffer( buf, n , yyscanner);
if ( ! b )
- YY_FATAL_ERROR( "bad buffer in pp_scan_bytes()" );
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
/* It's okay to grow etc. this buffer, and we should throw it
* away when we're done.
@@ -1979,15 +2516,25 @@
return b;
}
+
+
+
+
+
+
+
+
+
+
#ifndef YY_EXIT_FAILURE
#define YY_EXIT_FAILURE 2
#endif
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- (void) fprintf( stderr, "%s\n", msg );
+ fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
@@ -2008,23 +2555,29 @@
} \
while ( 0 )
+
+
/* Accessor methods (get/set functions) to struct members. */
+
/** Get the user-defined data for this scanner.
* @param yyscanner The scanner object.
*/
-YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner)
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyextra;
}
+
+
/** Get the current line number.
* @param yyscanner The scanner object.
*/
-int ppget_lineno (yyscan_t yyscanner)
+int yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2032,12 +2585,16 @@
return yylineno;
}
+
+
+
/** Get the current column number.
* @param yyscanner The scanner object.
*/
-int ppget_column (yyscan_t yyscanner)
+int yyget_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2045,155 +2602,194 @@
return yycolumn;
}
+
+
+
/** Get the input stream.
* @param yyscanner The scanner object.
*/
-FILE *ppget_in (yyscan_t yyscanner)
+FILE *yyget_in (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyin;
}
+
+
/** Get the output stream.
* @param yyscanner The scanner object.
*/
-FILE *ppget_out (yyscan_t yyscanner)
+FILE *yyget_out (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyout;
}
+
+
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-yy_size_t ppget_leng (yyscan_t yyscanner)
+int yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
}
+
/** Get the current token.
* @param yyscanner The scanner object.
*/
-char *ppget_text (yyscan_t yyscanner)
+char *yyget_text (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yytext;
}
+
+
/** Set the user-defined data. This data is never touched by the scanner.
* @param user_defined The data to be associated with this scanner.
* @param yyscanner The scanner object.
*/
-void ppset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyextra = user_defined ;
}
+
+
/** Set the current line number.
* @param _line_number line number
* @param yyscanner The scanner object.
*/
-void ppset_lineno (int _line_number , yyscan_t yyscanner)
+void yyset_lineno (int _line_number , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- YY_FATAL_ERROR( "ppset_lineno called with no buffer" );
+ YY_FATAL_ERROR( "yyset_lineno called with no buffer" );
yylineno = _line_number;
}
+
+
+
/** Set the current column.
* @param _column_no column number
* @param yyscanner The scanner object.
*/
-void ppset_column (int _column_no , yyscan_t yyscanner)
+void yyset_column (int _column_no , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
/* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- YY_FATAL_ERROR( "ppset_column called with no buffer" );
+ YY_FATAL_ERROR( "yyset_column called with no buffer" );
yycolumn = _column_no;
}
+
+
+
+
/** Set the input stream. This does not discard the current
* input buffer.
* @param _in_str A readable stream.
* @param yyscanner The scanner object.
- * @see pp_switch_to_buffer
+ * @see yy_switch_to_buffer
*/
-void ppset_in (FILE * _in_str , yyscan_t yyscanner)
+void yyset_in (FILE * _in_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyin = _in_str ;
}
-void ppset_out (FILE * _out_str , yyscan_t yyscanner)
+
+
+void yyset_out (FILE * _out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yyout = _out_str ;
}
-int ppget_debug (yyscan_t yyscanner)
+
+
+
+int yyget_debug (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yy_flex_debug;
}
-void ppset_debug (int _bdebug , yyscan_t yyscanner)
+
+
+void yyset_debug (int _bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_flex_debug = _bdebug ;
}
+
/* Accessor methods for yylval and yylloc */
-YYSTYPE * ppget_lval (yyscan_t yyscanner)
+
+YYSTYPE * yyget_lval (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yylval;
}
-void ppset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+
+
+void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylval = yylval_param;
}
-YYLTYPE *ppget_lloc (yyscan_t yyscanner)
+
+
+
+YYLTYPE *yyget_lloc (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yylloc;
}
-void ppset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
+
+
+void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yylloc = yylloc_param;
}
+
+
+
+
/* User-visible API */
-/* pplex_init is special because it creates the scanner itself, so it is
+/* yylex_init is special because it creates the scanner itself, so it is
* the ONLY reentrant function that doesn't take the scanner as the last argument.
* That's why we explicitly handle the declaration, instead of using our macros.
*/
-
-int pplex_init(yyscan_t* ptr_yy_globals)
-
+int yylex_init(yyscan_t* ptr_yy_globals)
{
if (ptr_yy_globals == NULL){
errno = EINVAL;
return 1;
}
- *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), NULL );
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
@@ -2206,111 +2802,127 @@
return yy_init_globals ( *ptr_yy_globals );
}
-/* pplex_init_extra has the same functionality as pplex_init, but follows the
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
* convention of taking the scanner as the last argument. Note however, that
* this is a *pointer* to a scanner, as it will be allocated by this call (and
* is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to ppalloc in
+ * The user defined value in the first argument will be available to yyalloc in
* the yyextra field.
*/
-
-int pplex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
{
struct yyguts_t dummy_yyguts;
- ppset_extra (yy_user_defined, &dummy_yyguts);
+ yyset_extra (yy_user_defined, &dummy_yyguts);
if (ptr_yy_globals == NULL){
errno = EINVAL;
return 1;
}
-
- *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return 1;
}
-
+
/* By setting to 0xAA, we expose bugs in
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- ppset_extra (yy_user_defined, *ptr_yy_globals);
-
+
+ yyset_extra (yy_user_defined, *ptr_yy_globals);
+
return yy_init_globals ( *ptr_yy_globals );
}
+
static int yy_init_globals (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Initialization is the same as for the non-reentrant scanner.
- * This function is called from pplex_destroy(), so don't allocate here.
+ * This function is called from yylex_destroy(), so don't allocate here.
*/
- yyg->yy_buffer_stack = 0;
+
+ yyg->yy_buffer_stack = NULL;
yyg->yy_buffer_stack_top = 0;
yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_c_buf_p = NULL;
yyg->yy_init = 0;
yyg->yy_start = 0;
+
yyg->yy_start_stack_ptr = 0;
yyg->yy_start_stack_depth = 0;
yyg->yy_start_stack = NULL;
+
+
+
+
+
/* Defined in main.c */
#ifdef YY_STDINIT
yyin = stdin;
yyout = stdout;
#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
+ yyin = NULL;
+ yyout = NULL;
#endif
/* For future reference: Set errno on error, since we are called by
- * pplex_init()
+ * yylex_init()
*/
return 0;
}
-/* pplex_destroy is for both reentrant and non-reentrant scanners. */
-int pplex_destroy (yyscan_t yyscanner)
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
- pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
YY_CURRENT_BUFFER_LVALUE = NULL;
- pppop_buffer_state(yyscanner);
+ yypop_buffer_state(yyscanner);
}
/* Destroy the stack itself. */
- ppfree(yyg->yy_buffer_stack ,yyscanner);
+ yyfree(yyg->yy_buffer_stack , yyscanner);
yyg->yy_buffer_stack = NULL;
+
/* Destroy the start condition stack. */
- ppfree(yyg->yy_start_stack ,yyscanner );
+ yyfree( yyg->yy_start_stack , yyscanner );
yyg->yy_start_stack = NULL;
+
+
+
/* Reset the globals. This is important in a non-reentrant scanner so the next time
- * pplex() is called, initialization will occur. */
+ * yylex() is called, initialization will occur. */
yy_init_globals( yyscanner);
/* Destroy the main struct (reentrant only). */
- ppfree ( yyscanner , yyscanner );
+ yyfree ( yyscanner , yyscanner );
yyscanner = NULL;
return 0;
}
+
+
/*
* Internal utility routines.
*/
+
+
#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -2321,8 +2933,10 @@
}
#endif
+
+
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
{
int n;
for ( n = 0; s[n]; ++n )
@@ -2332,14 +2946,18 @@
}
#endif
-void *ppalloc (yy_size_t size , yyscan_t yyscanner)
+
+
+void *yyalloc (yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- return (void *) malloc( size );
+ return malloc(size);
}
-void *pprealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+
+
+void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -2351,25 +2969,31 @@
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
- return (void *) realloc( (char *) ptr, size );
+ return realloc(ptr, size);
}
-void ppfree (void * ptr , yyscan_t yyscanner)
+
+
+void yyfree (void * ptr , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- free( (char *) ptr ); /* see pprealloc() for (char *) cast */
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
}
+
#define YYTABLES_NAME "yytables"
+
+
+
+
+
+
+
namespace pp {
-// TODO(alokp): Maximum token length should ideally be specified by
-// the preprocessor client, i.e., the compiler.
-const size_t Tokenizer::kMaxTokenLength = 256;
-
-Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0)
+Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(1024)
{
mContext.diagnostics = diagnostics;
}
@@ -2379,10 +3003,10 @@
destroyScanner();
}
-bool Tokenizer::init(int count, const char* const string[], const int length[])
+bool Tokenizer::init(size_t count, const char * const string[], const int length[])
{
- if (count < 0) return false;
- if ((count > 0) && (string == 0)) return false;
+ if ((count > 0) && (string == 0))
+ return false;
mContext.input = Input(count, string, length);
return initScanner();
@@ -2392,22 +3016,38 @@
{
// We use column number as file number.
// See macro yyfileno.
- ppset_column(file,mHandle);
+ yyset_column(file, mHandle);
}
void Tokenizer::setLineNumber(int line)
{
- ppset_lineno(line,mHandle);
+ yyset_lineno(line, mHandle);
}
-void Tokenizer::lex(Token* token)
+void Tokenizer::setMaxTokenSize(size_t maxTokenSize)
{
- token->type = pplex(&token->text,&token->location,mHandle);
- if (token->text.size() > kMaxTokenLength)
+ mMaxTokenSize = maxTokenSize;
+}
+
+void Tokenizer::lex(Token *token)
+{
+ int tokenType = yylex(&token->text, &token->location, mHandle);
+
+ if (tokenType == Token::GOT_ERROR)
{
- mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG,
+ mContext.diagnostics->report(Diagnostics::PP_TOKENIZER_ERROR, token->location, token->text);
+ token->type = Token::LAST;
+ }
+ else
+ {
+ token->type = tokenType;
+ }
+
+ if (token->text.size() > mMaxTokenSize)
+ {
+ mContext.diagnostics->report(Diagnostics::PP_TOKEN_TOO_LONG,
token->location, token->text);
- token->text.erase(kMaxTokenLength);
+ token->text.erase(mMaxTokenSize);
}
token->flags = 0;
@@ -2421,21 +3061,22 @@
bool Tokenizer::initScanner()
{
- if ((mHandle == NULL) && pplex_init_extra(&mContext,&mHandle))
+ if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle))
return false;
- pprestart(0,mHandle);
+ yyrestart(0, mHandle);
return true;
}
void Tokenizer::destroyScanner()
{
- if (mHandle == NULL)
+ if (mHandle == nullptr)
return;
- pplex_destroy(mHandle);
- mHandle = NULL;
+ yylex_destroy(mHandle);
+ mHandle = nullptr;
}
} // namespace pp
+
diff --git a/src/OpenGL/compiler/preprocessor/Tokenizer.h b/src/OpenGL/compiler/preprocessor/Tokenizer.h
index 3bad966..7227fe0 100644
--- a/src/OpenGL/compiler/preprocessor/Tokenizer.h
+++ b/src/OpenGL/compiler/preprocessor/Tokenizer.h
@@ -19,8 +19,6 @@
#include "Lexer.h"
#include "pp_utils.h"
-#include <algorithm>
-
namespace pp
{
@@ -31,7 +29,7 @@
public:
struct Context
{
- Diagnostics* diagnostics;
+ Diagnostics *diagnostics;
Input input;
// The location where yytext points to. Token location should track
@@ -42,25 +40,26 @@
bool leadingSpace;
bool lineStart;
};
- static const size_t kMaxTokenLength;
- Tokenizer(Diagnostics* diagnostics);
- ~Tokenizer();
+ Tokenizer(Diagnostics *diagnostics);
+ ~Tokenizer() override;
- bool init(int count, const char* const string[], const int length[]);
+ bool init(size_t count, const char *const string[], const int length[]);
void setFileNumber(int file);
void setLineNumber(int line);
+ void setMaxTokenSize(size_t maxTokenSize);
- virtual void lex(Token* token);
+ void lex(Token *token) override;
private:
PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer);
bool initScanner();
void destroyScanner();
- void* mHandle; // Scanner handle.
+ void *mHandle; // Scanner handle.
Context mContext; // Scanner extra.
+ size_t mMaxTokenSize; // Maximum token size
};
} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/Tokenizer.l b/src/OpenGL/compiler/preprocessor/Tokenizer.l
index 094627e..f99cfd4 100644
--- a/src/OpenGL/compiler/preprocessor/Tokenizer.l
+++ b/src/OpenGL/compiler/preprocessor/Tokenizer.l
@@ -39,14 +39,27 @@
}
%{
+#if defined(_MSC_VER)
+#pragma warning(disable: 4005)
+#endif
+
#include "Tokenizer.h"
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "Token.h"
#if defined(__GNUC__)
// Triggered by the auto-generated yy_fatal_error function.
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
+#elif defined(_MSC_VER)
+#pragma warning(disable: 4244)
+#endif
+
+// Workaround for flex using the register keyword, deprecated in C++11.
+#ifdef __cplusplus
+#if __cplusplus > 199711L
+#define register
+#endif
#endif
typedef std::string YYSTYPE;
@@ -80,7 +93,7 @@
} while(0);
#define YY_INPUT(buf, result, maxSize) \
- result = yyextra->input.read(buf, maxSize);
+ result = yyextra->input.read(buf, maxSize, &yylineno);
%}
@@ -109,11 +122,18 @@
/* Block comment */
/* Line breaks are just counted - not returned. */
- /* The comment is replaced by a single space. */
+ /* The comment is replaced by a single space. */
"/*" { BEGIN(COMMENT); }
<COMMENT>[^*\r\n]+
<COMMENT>"*"
-<COMMENT>{NEWLINE} { ++yylineno; }
+<COMMENT>{NEWLINE} {
+ if (yylineno == INT_MAX)
+ {
+ *yylval = "Integer overflow on line number";
+ return pp::Token::GOT_ERROR;
+ }
+ ++yylineno;
+}
<COMMENT>"*/" {
yyextra->leadingSpace = true;
BEGIN(INITIAL);
@@ -240,13 +260,16 @@
[ \t\v\f]+ { yyextra->leadingSpace = true; }
{NEWLINE} {
+ if (yylineno == INT_MAX)
+ {
+ *yylval = "Integer overflow on line number";
+ return pp::Token::GOT_ERROR;
+ }
++yylineno;
yylval->assign(1, '\n');
return '\n';
}
-\\{NEWLINE} { ++yylineno; }
-
. {
yylval->assign(1, yytext[0]);
return pp::Token::PP_OTHER;
@@ -257,23 +280,30 @@
// Set the location for EOF token manually.
pp::Input* input = &yyextra->input;
pp::Input::Location* scanLoc = &yyextra->scanLoc;
- int sIndexMax = std::max(0, input->count() - 1);
+ yy_size_t sIndexMax = input->count() ? input->count() - 1 : 0;
if (scanLoc->sIndex != sIndexMax)
{
// We can only reach here if there are empty strings at the
// end of the input.
scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
- yyfileno = sIndexMax; yylineno = 1;
+ // FIXME: this is not 64-bit clean.
+ yyfileno = static_cast<int>(sIndexMax); yylineno = 1;
}
yylloc->file = yyfileno;
yylloc->line = yylineno;
yylval->clear();
- if (YY_START == COMMENT)
+ // Line number overflows fake EOFs to exit early, check for this case.
+ if (yylineno == INT_MAX) {
+ yyextra->diagnostics->report(pp::Diagnostics::PP_TOKENIZER_ERROR,
+ pp::SourceLocation(yyfileno, yylineno),
+ "Integer overflow on line number");
+ }
+ else if (YY_START == COMMENT)
{
- yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT,
+ yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT,
pp::SourceLocation(yyfileno, yylineno),
- "");
+ "EOF while in a comment");
}
yyterminate();
}
@@ -282,11 +312,7 @@
namespace pp {
-// TODO(alokp): Maximum token length should ideally be specified by
-// the preprocessor client, i.e., the compiler.
-const size_t Tokenizer::kMaxTokenLength = 256;
-
-Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0)
+Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(1024)
{
mContext.diagnostics = diagnostics;
}
@@ -296,10 +322,10 @@
destroyScanner();
}
-bool Tokenizer::init(int count, const char* const string[], const int length[])
+bool Tokenizer::init(size_t count, const char * const string[], const int length[])
{
- if (count < 0) return false;
- if ((count > 0) && (string == 0)) return false;
+ if ((count > 0) && (string == 0))
+ return false;
mContext.input = Input(count, string, length);
return initScanner();
@@ -317,14 +343,30 @@
yyset_lineno(line, mHandle);
}
-void Tokenizer::lex(Token* token)
+void Tokenizer::setMaxTokenSize(size_t maxTokenSize)
{
- token->type = yylex(&token->text, &token->location, mHandle);
- if (token->text.size() > kMaxTokenLength)
+ mMaxTokenSize = maxTokenSize;
+}
+
+void Tokenizer::lex(Token *token)
+{
+ int tokenType = yylex(&token->text, &token->location, mHandle);
+
+ if (tokenType == Token::GOT_ERROR)
{
- mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG,
+ mContext.diagnostics->report(Diagnostics::PP_TOKENIZER_ERROR, token->location, token->text);
+ token->type = Token::LAST;
+ }
+ else
+ {
+ token->type = tokenType;
+ }
+
+ if (token->text.size() > mMaxTokenSize)
+ {
+ mContext.diagnostics->report(Diagnostics::PP_TOKEN_TOO_LONG,
token->location, token->text);
- token->text.erase(kMaxTokenLength);
+ token->text.erase(mMaxTokenSize);
}
token->flags = 0;
@@ -338,7 +380,7 @@
bool Tokenizer::initScanner()
{
- if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle))
+ if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle))
return false;
yyrestart(0, mHandle);
@@ -347,11 +389,11 @@
void Tokenizer::destroyScanner()
{
- if (mHandle == NULL)
+ if (mHandle == nullptr)
return;
yylex_destroy(mHandle);
- mHandle = NULL;
+ mHandle = nullptr;
}
} // namespace pp
diff --git a/src/OpenGL/compiler/preprocessor/numeric_lex.h b/src/OpenGL/compiler/preprocessor/numeric_lex.h
index f57410c..ed22e03 100644
--- a/src/OpenGL/compiler/preprocessor/numeric_lex.h
+++ b/src/OpenGL/compiler/preprocessor/numeric_lex.h
@@ -18,6 +18,7 @@
#define COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
#include <sstream>
+#include <cmath>
namespace pp {
@@ -62,7 +63,7 @@
stream.imbue(std::locale::classic());
stream >> (*value);
- return !stream.fail();
+ return !stream.fail() && std::isfinite(*value);
}
} // namespace pp.
diff --git a/src/OpenGL/compiler/preprocessor/preprocessor.vcxproj b/src/OpenGL/compiler/preprocessor/preprocessor.vcxproj
index 701e965..0060904 100644
--- a/src/OpenGL/compiler/preprocessor/preprocessor.vcxproj
+++ b/src/OpenGL/compiler/preprocessor/preprocessor.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,33 +21,34 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{92940255-AB4B-42FB-A2C4-0FAB19C3C48A}</ProjectGuid>
<RootNamespace>preprocessor</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -89,6 +90,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4005;</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -102,6 +104,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4005;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -117,6 +120,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4005;</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -134,6 +138,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>4005;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -142,8 +147,8 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClInclude Include="Diagnostics.h" />
- <ClInclude Include="DirectiveHandler.h" />
+ <ClInclude Include="DiagnosticsBase.h" />
+ <ClInclude Include="DirectiveHandlerBase.h" />
<ClInclude Include="DirectiveParser.h" />
<ClInclude Include="ExpressionParser.h" />
<ClInclude Include="Input.h" />
@@ -159,8 +164,8 @@
<ClInclude Include="Tokenizer.h" />
</ItemGroup>
<ItemGroup>
- <ClCompile Include="Diagnostics.cpp" />
- <ClCompile Include="DirectiveHandler.cpp" />
+ <ClCompile Include="DiagnosticsBase.cpp" />
+ <ClCompile Include="DirectiveHandlerBase.cpp" />
<ClCompile Include="DirectiveParser.cpp" />
<ClCompile Include="ExpressionParser.cpp" />
<ClCompile Include="Input.cpp" />
diff --git a/src/OpenGL/compiler/preprocessor/preprocessor.vcxproj.filters b/src/OpenGL/compiler/preprocessor/preprocessor.vcxproj.filters
index d68cbe2..02c06a0 100644
--- a/src/OpenGL/compiler/preprocessor/preprocessor.vcxproj.filters
+++ b/src/OpenGL/compiler/preprocessor/preprocessor.vcxproj.filters
@@ -15,12 +15,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="Diagnostics.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="DirectiveHandler.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="DirectiveParser.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -60,14 +54,14 @@
<ClInclude Include="Tokenizer.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="DiagnosticsBase.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="DirectiveHandlerBase.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="Diagnostics.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="DirectiveHandler.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="DirectiveParser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -95,9 +89,15 @@
<ClCompile Include="Tokenizer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="DiagnosticsBase.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="DirectiveHandlerBase.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Tokenizer.l" />
<None Include="ExpressionParser.y" />
</ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/src/OpenGL/compiler/util.cpp b/src/OpenGL/compiler/util.cpp
index 2905c1d..bd9783c 100644
--- a/src/OpenGL/compiler/util.cpp
+++ b/src/OpenGL/compiler/util.cpp
@@ -32,3 +32,11 @@
*value = std::numeric_limits<int>::max();
return success;
}
+
+bool atou_clamp(const char *str, unsigned int *value)
+{
+ bool success = pp::numeric_lex_int(str, value);
+ if(!success)
+ *value = std::numeric_limits<unsigned int>::max();
+ return success;
+}
diff --git a/src/OpenGL/compiler/util.h b/src/OpenGL/compiler/util.h
index a5c4842..563407e 100644
--- a/src/OpenGL/compiler/util.h
+++ b/src/OpenGL/compiler/util.h
@@ -21,14 +21,18 @@
// atof_clamp is like atof but
// 1. it forces C locale, i.e. forcing '.' as decimal point.
-// 2. it clamps the value to -FLT_MAX or FLT_MAX if overflow happens.
+// 2. it sets the value to FLT_MAX if overflow happens.
// Return false if overflow happens.
bool atof_clamp(const char *str, float *value);
-// If overflow happens, clamp the value to INT_MIN or INT_MAX.
+// If overflow happens, value is set to INT_MAX.
// Return false if overflow happens.
bool atoi_clamp(const char *str, int *value);
+// If overflow happens, value is set to UINT_MAX.
+// Return false if overflow happens.
+bool atou_clamp(const char *str, unsigned int *value);
+
#ifdef __cplusplus
} // end extern "C"
#endif
diff --git a/src/OpenGL/libEGL/Android.mk b/src/OpenGL/libEGL/Android.mk
index 6e78d63..64ccc55 100644
--- a/src/OpenGL/libEGL/Android.mk
+++ b/src/OpenGL/libEGL/Android.mk
@@ -63,7 +63,8 @@
endif
COMMON_LDFLAGS := \
- -Wl,--version-script=$(LOCAL_PATH)/exports.map \
+ -Wl,--version-script=$(LOCAL_PATH)/libEGL.lds \
+ -Wl,--gc-sections \
-Wl,--hash-style=sysv
include $(CLEAR_VARS)
@@ -71,14 +72,10 @@
ifdef TARGET_2ND_ARCH
ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
LOCAL_MULTILIB := first
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
-else
-LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl
endif
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
endif
+LOCAL_MODULE_RELATIVE_PATH := egl
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_CLANG := true
LOCAL_SRC_FILES := $(COMMON_SRC_FILES)
@@ -95,14 +92,10 @@
ifdef TARGET_2ND_ARCH
ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
LOCAL_MULTILIB := first
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
-else
-LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl
endif
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
endif
+LOCAL_MODULE_RELATIVE_PATH := egl
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_CLANG := true
LOCAL_SRC_FILES := $(COMMON_SRC_FILES)
diff --git a/src/OpenGL/libEGL/BUILD.gn b/src/OpenGL/libEGL/BUILD.gn
index 68a10bc..24727cf 100644
--- a/src/OpenGL/libEGL/BUILD.gn
+++ b/src/OpenGL/libEGL/BUILD.gn
@@ -74,7 +74,7 @@
} else if (is_linux) {
sources += [ "../../Main/libX11.cpp" ]
ldflags =
- [ "-Wl,--version-script=" + rebase_path("exports.map", root_build_dir) ]
+ [ "-Wl,--version-script=" + rebase_path("libEGL.lds", root_build_dir) ]
}
configs = [ ":swiftshader_libEGL_private_config" ]
diff --git a/src/OpenGL/libEGL/Config.cpp b/src/OpenGL/libEGL/Config.cpp
index a1c800b..2595ef1 100644
--- a/src/OpenGL/libEGL/Config.cpp
+++ b/src/OpenGL/libEGL/Config.cpp
@@ -34,16 +34,8 @@
namespace egl
{
-// OpenGL ES 3.0 support is not conformant yet, but can be used for testing purposes. Expose it as conformant configs
-// if strict conformance advertisement isn't required. If strict conformance advertisement is required, expose them
-// as non-conformant configs, but only when EGL_CONFIG_CAVEAT is EGL_NON_CONFORMANT_CONFIG or EGL_DONT_CARE.
-#if defined(__ANDROID__) || defined(STRICT_CONFORMANCE)
-const bool strictConformance = true;
-#else
-const bool strictConformance = false;
-#endif
-Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample, bool conformant)
+Config::Config(sw::Format displayFormat, EGLint minInterval, EGLint maxInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
: mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
{
mBindToTextureRGB = EGL_FALSE;
@@ -127,9 +119,9 @@
mBufferSize = mRedSize + mGreenSize + mBlueSize + mLuminanceSize + mAlphaSize;
mAlphaMaskSize = 0;
mColorBufferType = EGL_RGB_BUFFER;
- mConfigCaveat = (conformant || !strictConformance) ? EGL_NONE : EGL_NON_CONFORMANT_CONFIG;
+ mConfigCaveat = EGL_NONE;
mConfigID = 0;
- mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | (strictConformance ? 0 : EGL_OPENGL_ES3_BIT);
+ mConformant = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
switch(depthStencilFormat)
{
@@ -186,7 +178,7 @@
mMinSwapInterval = minInterval;
mNativeRenderable = EGL_FALSE;
mNativeVisualType = 0;
- mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | ((conformant && strictConformance) ? 0 : EGL_OPENGL_ES3_BIT);
+ mRenderableType = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
mSampleBuffers = (multiSample > 0) ? 1 : 0;
mSamples = multiSample;
mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
@@ -338,14 +330,8 @@
void ConfigSet::add(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample)
{
- Config conformantConfig(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample, true);
+ Config conformantConfig(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample);
mSet.insert(conformantConfig);
-
- if(strictConformance) // When strict conformance is required, add non-conformant configs explicitly as such.
- {
- Config nonConformantConfig(displayFormat, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample, false);
- mSet.insert(nonConformantConfig);
- }
}
size_t ConfigSet::size() const
diff --git a/src/OpenGL/libEGL/Config.h b/src/OpenGL/libEGL/Config.h
index a15fbd1..46719e1 100644
--- a/src/OpenGL/libEGL/Config.h
+++ b/src/OpenGL/libEGL/Config.h
@@ -32,7 +32,7 @@
class Config
{
public:
- Config(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample, bool conformant);
+ Config(sw::Format displayFormat, EGLint minSwapInterval, EGLint maxSwapInterval, sw::Format renderTargetFormat, sw::Format depthStencilFormat, EGLint multiSample);
EGLConfig getHandle() const;
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index 0ae67bd..0e58125 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -567,11 +567,14 @@
XWindowAttributes windowAttributes;
Status status = libX11->XGetWindowAttributes((::Display*)nativeDisplay, window, &windowAttributes);
- return status == True;
+ return status != 0;
}
return false;
#elif defined(__APPLE__)
return sw::OSX::IsValidWindow(window);
+ #elif defined(__Fuchsia__)
+ // TODO(crbug.com/800951): Integrate with Mozart.
+ return true;
#else
#error "Display::isValidWindow unimplemented for this platform"
return false;
@@ -580,11 +583,11 @@
bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
{
- for(SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+ for(const auto &surface : mSurfaceSet)
{
- if((*surface)->isWindowSurface())
+ if(surface->isWindowSurface())
{
- if((*surface)->getWindowHandle() == window)
+ if(surface->getWindowHandle() == window)
{
return true;
}
@@ -744,6 +747,8 @@
}
#elif defined(__APPLE__)
return sw::FORMAT_A8B8G8R8;
+ #elif defined(__Fuchsia__)
+ return sw::FORMAT_A8B8G8R8;
#else
#error "Display::isValidWindow unimplemented for this platform"
#endif
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index 8cb3b39..d373990 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -76,14 +76,14 @@
{
ASSERT(!backBuffer && !depthStencil);
- if(libGLES_CM)
- {
- backBuffer = libGLES_CM->createBackBuffer(width, height, config->mRenderTargetFormat, config->mSamples);
- }
- else if(libGLESv2)
+ if(libGLESv2)
{
backBuffer = libGLESv2->createBackBuffer(width, height, config->mRenderTargetFormat, config->mSamples);
}
+ else if(libGLES_CM)
+ {
+ backBuffer = libGLES_CM->createBackBuffer(width, height, config->mRenderTargetFormat, config->mSamples);
+ }
if(!backBuffer)
{
@@ -94,14 +94,14 @@
if(config->mDepthStencilFormat != sw::FORMAT_NULL)
{
- if(libGLES_CM)
- {
- depthStencil = libGLES_CM->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples);
- }
- else if(libGLESv2)
+ if(libGLESv2)
{
depthStencil = libGLESv2->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples);
}
+ else if(libGLES_CM)
+ {
+ depthStencil = libGLES_CM->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples);
+ }
if(!depthStencil)
{
@@ -182,11 +182,6 @@
return config->mSurfaceType;
}
-sw::Format Surface::getInternalFormat() const
-{
- return config->mRenderTargetFormat;
-}
-
EGLint Surface::getWidth() const
{
return width;
@@ -259,9 +254,7 @@
{
if(backBuffer && frameBuffer)
{
- void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
- frameBuffer->flip(source, backBuffer->sw::Surface::getInternalFormat(), backBuffer->getInternalPitchB());
- backBuffer->unlockInternal();
+ frameBuffer->flip(backBuffer);
checkForResize();
}
@@ -276,10 +269,11 @@
{
#if defined(_WIN32)
RECT client;
- if(!GetClientRect(window, &client))
+ BOOL status = GetClientRect(window, &client);
+
+ if(status == 0)
{
- ASSERT(false);
- return false;
+ return error(EGL_BAD_NATIVE_WINDOW, false);
}
int windowWidth = client.right - client.left;
@@ -289,7 +283,12 @@
int windowHeight; window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);
#elif defined(__linux__)
XWindowAttributes windowAttributes;
- libX11->XGetWindowAttributes((::Display*)display->getNativeDisplay(), window, &windowAttributes);
+ Status status = libX11->XGetWindowAttributes((::Display*)display->getNativeDisplay(), window, &windowAttributes);
+
+ if(status == 0)
+ {
+ return error(EGL_BAD_NATIVE_WINDOW, false);
+ }
int windowWidth = windowAttributes.width;
int windowHeight = windowAttributes.height;
@@ -297,6 +296,10 @@
int windowWidth;
int windowHeight;
sw::OSX::GetNativeWindowSize(window, windowWidth, windowHeight);
+ #elif defined(__Fuchsia__)
+ // TODO(crbug.com/800951): Integrate with Mozart.
+ int windowWidth = 100;
+ int windowHeight = 100;
#else
#error "WindowSurface::checkForResize unimplemented for this platform"
#endif
@@ -333,14 +336,14 @@
if(window)
{
- if(libGLES_CM)
- {
- frameBuffer = libGLES_CM->createFrameBuffer(display->getNativeDisplay(), window, width, height);
- }
- else if(libGLESv2)
+ if(libGLESv2)
{
frameBuffer = libGLESv2->createFrameBuffer(display->getNativeDisplay(), window, width, height);
}
+ else if(libGLES_CM)
+ {
+ frameBuffer = libGLES_CM->createFrameBuffer(display->getNativeDisplay(), window, width, height);
+ }
if(!frameBuffer)
{
diff --git a/src/OpenGL/libEGL/Surface.hpp b/src/OpenGL/libEGL/Surface.hpp
index e140a8e..2e9e26b 100644
--- a/src/OpenGL/libEGL/Surface.hpp
+++ b/src/OpenGL/libEGL/Surface.hpp
@@ -45,7 +45,6 @@
virtual EGLint getConfigID() const;
virtual EGLenum getSurfaceType() const;
- sw::Format getInternalFormat() const override;
EGLint getWidth() const override;
EGLint getHeight() const override;
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 21ef933..5944efd 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -29,6 +29,7 @@
#include "Main/libX11.hpp"
#endif
+#include <algorithm>
#include <string.h>
using namespace egl;
@@ -174,6 +175,7 @@
if(dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
{
return success(
+ "EGL_KHR_client_get_all_proc_addresses "
#if defined(__linux__) && !defined(__ANDROID__)
"EGL_KHR_platform_gbm "
"EGL_KHR_platform_x11 "
@@ -195,6 +197,7 @@
return success("OpenGL_ES");
case EGL_EXTENSIONS:
return success("EGL_KHR_create_context "
+ "EGL_KHR_get_all_proc_addresses "
"EGL_KHR_gl_texture_2D_image "
"EGL_KHR_gl_texture_cubemap_image "
"EGL_KHR_gl_renderbuffer_image "
@@ -477,9 +480,15 @@
{
TRACE("()");
- UNIMPLEMENTED(); // FIXME
+ // eglWaitClient is ignored if there is no current EGL rendering context for the current rendering API.
+ egl::Context *context = egl::getCurrentContext();
- return success(EGL_FALSE);
+ if(context)
+ {
+ context->finish();
+ }
+
+ return success(EGL_TRUE);
}
EGLBoolean ReleaseThread(void)
@@ -910,18 +919,46 @@
{
TRACE("()");
- UNIMPLEMENTED(); // FIXME
+ // glWaitGL is ignored if there is no current EGL rendering context for OpenGL ES.
+ egl::Context *context = egl::getCurrentContext();
- return success(EGL_FALSE);
+ if(context)
+ {
+ context->finish();
+ }
+
+ return success(EGL_TRUE);
}
EGLBoolean WaitNative(EGLint engine)
{
TRACE("(EGLint engine = %d)", engine);
- UNIMPLEMENTED(); // FIXME
+ if(engine != EGL_CORE_NATIVE_ENGINE)
+ {
+ return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ }
- return success(EGL_FALSE);
+ // eglWaitNative is ignored if there is no current EGL rendering context.
+ egl::Context *context = egl::getCurrentContext();
+
+ if(context)
+ {
+ #if defined(__linux__) && !defined(__ANDROID__)
+ egl::Display *display = context->getDisplay();
+
+ if(!display)
+ {
+ return error(EGL_BAD_DISPLAY, EGL_FALSE);
+ }
+
+ libX11->XSync((::Display*)display->getNativeDisplay(), False);
+ #else
+ UNIMPLEMENTED();
+ #endif
+ }
+
+ return success(EGL_TRUE);
}
EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface)
@@ -1241,34 +1278,85 @@
{
TRACE("(const char *procname = \"%s\")", procname);
- struct Extension
+ struct Function
{
const char *name;
__eglMustCastToProperFunctionPointerType address;
};
- static const Extension eglExtensions[] =
+ struct CompareFunctor
{
- #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
-
- EXTENSION(eglCreateImageKHR),
- EXTENSION(eglDestroyImageKHR),
- EXTENSION(eglGetPlatformDisplayEXT),
- EXTENSION(eglCreatePlatformWindowSurfaceEXT),
- EXTENSION(eglCreatePlatformPixmapSurfaceEXT),
- EXTENSION(eglCreateSyncKHR),
- EXTENSION(eglDestroySyncKHR),
- EXTENSION(eglClientWaitSyncKHR),
- EXTENSION(eglGetSyncAttribKHR),
-
- #undef EXTENSION
+ bool operator()(const Function &a, const Function &b) const
+ {
+ return strcmp(a.name, b.name) < 0;
+ }
};
- for(unsigned int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
+ // This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
+ // The Unix command "LC_COLLATE=C sort" will generate the correct order.
+ static const Function eglFunctions[] =
{
- if(strcmp(procname, eglExtensions[ext].name) == 0)
+ #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
+
+ FUNCTION(eglBindAPI),
+ FUNCTION(eglBindTexImage),
+ FUNCTION(eglChooseConfig),
+ FUNCTION(eglClientWaitSyncKHR),
+ FUNCTION(eglCopyBuffers),
+ FUNCTION(eglCreateContext),
+ FUNCTION(eglCreateImageKHR),
+ FUNCTION(eglCreatePbufferFromClientBuffer),
+ FUNCTION(eglCreatePbufferSurface),
+ FUNCTION(eglCreatePixmapSurface),
+ FUNCTION(eglCreatePlatformPixmapSurfaceEXT),
+ FUNCTION(eglCreatePlatformWindowSurfaceEXT),
+ FUNCTION(eglCreateSyncKHR),
+ FUNCTION(eglCreateWindowSurface),
+ FUNCTION(eglDestroyContext),
+ FUNCTION(eglDestroyImageKHR),
+ FUNCTION(eglDestroySurface),
+ FUNCTION(eglDestroySyncKHR),
+ FUNCTION(eglGetConfigAttrib),
+ FUNCTION(eglGetConfigs),
+ FUNCTION(eglGetCurrentContext),
+ FUNCTION(eglGetCurrentDisplay),
+ FUNCTION(eglGetCurrentSurface),
+ FUNCTION(eglGetDisplay),
+ FUNCTION(eglGetError),
+ FUNCTION(eglGetPlatformDisplayEXT),
+ FUNCTION(eglGetProcAddress),
+ FUNCTION(eglGetSyncAttribKHR),
+ FUNCTION(eglInitialize),
+ FUNCTION(eglMakeCurrent),
+ FUNCTION(eglQueryAPI),
+ FUNCTION(eglQueryContext),
+ FUNCTION(eglQueryString),
+ FUNCTION(eglQuerySurface),
+ FUNCTION(eglReleaseTexImage),
+ FUNCTION(eglReleaseThread),
+ FUNCTION(eglSurfaceAttrib),
+ FUNCTION(eglSwapBuffers),
+ FUNCTION(eglSwapInterval),
+ FUNCTION(eglTerminate),
+ FUNCTION(eglWaitClient),
+ FUNCTION(eglWaitGL),
+ FUNCTION(eglWaitNative),
+
+ #undef FUNCTION
+ };
+
+ static const size_t numFunctions = sizeof eglFunctions / sizeof(Function);
+ static const Function *const eglFunctionsEnd = eglFunctions + numFunctions;
+
+ Function needle;
+ needle.name = procname;
+
+ if(procname && strncmp("egl", procname, 3) == 0)
+ {
+ const Function *result = std::lower_bound(eglFunctions, eglFunctionsEnd, needle, CompareFunctor());
+ if (result != eglFunctionsEnd && strcmp(procname, result->name) == 0)
{
- return success((__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address);
+ return success((__eglMustCastToProperFunctionPointerType)result->address);
}
}
diff --git a/src/OpenGL/libEGL/libEGL.hpp b/src/OpenGL/libEGL/libEGL.hpp
index 683b0d1..77ddf70 100644
--- a/src/OpenGL/libEGL/libEGL.hpp
+++ b/src/OpenGL/libEGL/libEGL.hpp
@@ -118,6 +118,8 @@
#else
const char *libEGL_lib[] = {"libEGL_translator.dylib", "libEGL.so", "libEGL.dylib", "libswiftshader_libEGL.dylib"};
#endif
+ #elif defined(__Fuchsia__)
+ const char *libEGL_lib[] = {"libEGL.so"};
#else
#error "libEGL::loadExports unimplemented for this platform"
#endif
diff --git a/src/OpenGL/libEGL/exports.map b/src/OpenGL/libEGL/libEGL.lds
similarity index 99%
rename from src/OpenGL/libEGL/exports.map
rename to src/OpenGL/libEGL/libEGL.lds
index 8455dc9..7a2a479 100644
--- a/src/OpenGL/libEGL/exports.map
+++ b/src/OpenGL/libEGL/libEGL.lds
@@ -56,4 +56,4 @@
local:
*;
-};
+};
\ No newline at end of file
diff --git a/src/OpenGL/libEGL/libEGL.vcxproj b/src/OpenGL/libEGL/libEGL.vcxproj
index 032077b..172d6b8 100644
--- a/src/OpenGL/libEGL/libEGL.vcxproj
+++ b/src/OpenGL/libEGL/libEGL.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -30,41 +30,42 @@
<ProjectGuid>{E746FCA9-64C3-433E-85E8-9A5A67AB7ED6}</ProjectGuid>
<RootNamespace>libEGL</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -131,6 +132,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DisableSpecificWarnings>5030</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -162,6 +164,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DisableSpecificWarnings>5030</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -194,6 +197,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DisableSpecificWarnings>5030</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -226,6 +230,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DisableSpecificWarnings>5030</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -260,6 +265,7 @@
<OmitFramePointers>false</OmitFramePointers>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -292,6 +298,7 @@
<OmitFramePointers>false</OmitFramePointers>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
diff --git a/src/OpenGL/libEGL/main.cpp b/src/OpenGL/libEGL/main.cpp
index 3a8d1ce..b953e4b 100644
--- a/src/OpenGL/libEGL/main.cpp
+++ b/src/OpenGL/libEGL/main.cpp
@@ -48,14 +48,7 @@
currentTLS = sw::Thread::allocateLocalStorageKey();
}
- Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
-
- if(!current)
- {
- current = new Current;
-
- sw::Thread::setLocalStorage(currentTLS, current);
- }
+ Current *current = (Current*)sw::Thread::allocateLocalStorage(currentTLS, sizeof(Current));
current->error = EGL_SUCCESS;
current->API = EGL_OPENGL_ES_API;
@@ -72,8 +65,7 @@
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
- delete (Current*)sw::Thread::getLocalStorage(currentTLS);
- sw::Thread::setLocalStorage(currentTLS, nullptr);
+ sw::Thread::freeLocalStorage(currentTLS);
}
CONSTRUCTOR void attachProcess()
diff --git a/src/OpenGL/libGL/Context.cpp b/src/OpenGL/libGL/Context.cpp
index 4922ecb..8f8d96a 100644
--- a/src/OpenGL/libGL/Context.cpp
+++ b/src/OpenGL/libGL/Context.cpp
@@ -2109,7 +2109,7 @@
if(baseTexture && textureUsed)
{
- int levelCount = baseTexture->getLevelCount();
+ int topLevel = baseTexture->getTopLevel();
if(baseTexture->getTarget() == GL_TEXTURE_2D)
{
@@ -2123,9 +2123,9 @@
{
surfaceLevel = 0;
}
- else if(surfaceLevel >= levelCount)
+ else if(surfaceLevel > topLevel)
{
- surfaceLevel = levelCount - 1;
+ surfaceLevel = topLevel;
}
Image *surface = texture->getImage(surfaceLevel);
@@ -2146,9 +2146,9 @@
{
surfaceLevel = 0;
}
- else if(surfaceLevel >= levelCount)
+ else if(surfaceLevel > topLevel)
{
- surfaceLevel = levelCount - 1;
+ surfaceLevel = topLevel;
}
Image *surface = cubeTexture->getImage(face, surfaceLevel);
@@ -2477,7 +2477,7 @@
{
if(!mState.currentProgram)
{
- return error(GL_INVALID_OPERATION);
+ return;
}
if(!indices && !mState.elementArrayBuffer)
diff --git a/src/OpenGL/libGL/Context.h b/src/OpenGL/libGL/Context.h
index 877d768..10f4ae0 100644
--- a/src/OpenGL/libGL/Context.h
+++ b/src/OpenGL/libGL/Context.h
@@ -328,12 +328,10 @@
const GLenum compressedTextureFormats[] =
{
-#if (S3TC_SUPPORT)
GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
-#endif
};
const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
diff --git a/src/OpenGL/libGL/Device.cpp b/src/OpenGL/libGL/Device.cpp
index 736bb99..be7d10e 100644
--- a/src/OpenGL/libGL/Device.cpp
+++ b/src/OpenGL/libGL/Device.cpp
@@ -621,7 +621,8 @@
}
else
{
- blit(source, sRect, dest, dRect, scaling && filter);
+ sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
+ blit(source, sRectF, dest, dRect, scaling && filter);
}
return true;
diff --git a/src/OpenGL/libGL/Image.cpp b/src/OpenGL/libGL/Image.cpp
index 8126de2..b86b689 100644
--- a/src/OpenGL/libGL/Image.cpp
+++ b/src/OpenGL/libGL/Image.cpp
@@ -33,20 +33,20 @@
return texture->getResource();
}
- return 0;
+ return nullptr;
}
Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
- : parentTexture(parentTexture), width(width), height(height), format(format), type(type)
+ : sw::Surface(getParentResource(parentTexture), width, height, 1, 0, 1, selectInternalFormat(format, type), true, true)
+ , parentTexture(parentTexture), width(width), height(height), format(format), type(type)
, internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1)
- , sw::Surface(getParentResource(parentTexture), width, height, 1, selectInternalFormat(format, type), true, true)
{
referenceCount = 1;
}
Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget)
- : parentTexture(parentTexture), width(width), height(height), internalFormat(internalFormat), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), multiSampleDepth(multiSampleDepth)
- , sw::Surface(getParentResource(parentTexture), width, height, multiSampleDepth, internalFormat, lockable, renderTarget)
+ : sw::Surface(getParentResource(parentTexture), width, height, 1, 0, multiSampleDepth, internalFormat, lockable, renderTarget)
+ , parentTexture(parentTexture), width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), multiSampleDepth(multiSampleDepth)
{
referenceCount = 1;
}
@@ -141,7 +141,7 @@
void Image::unbind()
{
- parentTexture = 0;
+ parentTexture = nullptr;
release();
}
@@ -152,10 +152,8 @@
{
return sw::FORMAT_NULL;
}
- else
- #if S3TC_SUPPORT
- if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
- format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ else if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
{
return sw::FORMAT_DXT1;
}
@@ -167,9 +165,7 @@
{
return sw::FORMAT_DXT5;
}
- else
- #endif
- if(type == GL_FLOAT)
+ else if(type == GL_FLOAT)
{
return sw::FORMAT_A32B32G32R32F;
}
diff --git a/src/OpenGL/libGL/Program.cpp b/src/OpenGL/libGL/Program.cpp
index db3a860..1a55bce 100644
--- a/src/OpenGL/libGL/Program.cpp
+++ b/src/OpenGL/libGL/Program.cpp
@@ -73,7 +73,7 @@
{
}
- Program::Program(ResourceManager *manager, GLuint handle) : resourceManager(manager), handle(handle), serial(issueSerial())
+ Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle)
{
device = getDevice();
@@ -968,8 +968,8 @@
if(available)
{
- varying->reg = r;
- varying->col = 0;
+ varying->registerIndex = r;
+ varying->column = 0;
for(int y = 0; y < n; y++)
{
@@ -1002,8 +1002,8 @@
if(available)
{
- varying->reg = r;
- varying->col = 2;
+ varying->registerIndex = r;
+ varying->column = 2;
for(int y = 0; y < n; y++)
{
@@ -1046,7 +1046,7 @@
{
if(!packing[r][column])
{
- varying->reg = r;
+ varying->registerIndex = r;
for(int y = r; y < r + n; y++)
{
@@ -1057,7 +1057,7 @@
}
}
- varying->col = column;
+ varying->column = column;
success = true;
}
@@ -1125,8 +1125,8 @@
{
if(output->name == input->name)
{
- int in = input->reg;
- int out = output->reg;
+ int in = input->registerIndex;
+ int out = output->registerIndex;
int components = VariableColumnCount(output->type);
int registers = VariableRowCount(output->type) * output->size();
diff --git a/src/OpenGL/libGL/Surface.cpp b/src/OpenGL/libGL/Surface.cpp
index a6ec333..f5bfa0e 100644
--- a/src/OpenGL/libGL/Surface.cpp
+++ b/src/OpenGL/libGL/Surface.cpp
@@ -160,9 +160,7 @@
{
if(backBuffer)
{
- void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
- frameBuffer->flip(source, backBuffer->Surface::getInternalFormat(), backBuffer->getInternalPitchB());
- backBuffer->unlockInternal();
+ frameBuffer->flip(backBuffer);
checkForResize();
}
diff --git a/src/OpenGL/libGL/Surface.h b/src/OpenGL/libGL/Surface.h
index 20ab599..70f910f 100644
--- a/src/OpenGL/libGL/Surface.h
+++ b/src/OpenGL/libGL/Surface.h
@@ -74,8 +74,8 @@
const NativeWindowType mWindow; // Window that the surface is created for.
bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
- GLint mHeight; // Height of surface
GLint mWidth; // Width of surface
+ GLint mHeight; // Height of surface
GLenum mTextureFormat; // Format of texture: RGB, RGBA, or no texture
GLenum mTextureTarget; // Type of texture: 2D or no texture
GLint mSwapInterval;
diff --git a/src/OpenGL/libGL/Texture.cpp b/src/OpenGL/libGL/Texture.cpp
index e0756d2..70ff9b2 100644
--- a/src/OpenGL/libGL/Texture.cpp
+++ b/src/OpenGL/libGL/Texture.cpp
@@ -181,7 +181,7 @@
void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
{
- if(pixels && image)
+ if(pixels && image && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
{
image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);
}
@@ -232,7 +232,7 @@
return error(GL_INVALID_OPERATION);
}
- if(pixels)
+ if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
{
image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);
}
@@ -353,7 +353,7 @@
return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
}
-int Texture2D::getLevelCount() const
+int Texture2D::getTopLevel() const
{
ASSERT(isSamplerComplete());
int levels = 0;
@@ -726,7 +726,7 @@
return image[face][level] ? image[face][level]->getInternalFormat() : sw::FORMAT_NULL;
}
-int TextureCubeMap::getLevelCount() const
+int TextureCubeMap::getTopLevel() const
{
ASSERT(isSamplerComplete());
int levels = 0;
diff --git a/src/OpenGL/libGL/Texture.h b/src/OpenGL/libGL/Texture.h
index ed124c8..483dc77 100644
--- a/src/OpenGL/libGL/Texture.h
+++ b/src/OpenGL/libGL/Texture.h
@@ -77,7 +77,7 @@
virtual GLenum getFormat(GLenum target, GLint level) const = 0;
virtual GLenum getType(GLenum target, GLint level) const = 0;
virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
- virtual int getLevelCount() const = 0;
+ virtual int getTopLevel() const = 0;
virtual bool isSamplerComplete() const = 0;
virtual bool isCompressed(GLenum target, GLint level) const = 0;
@@ -126,7 +126,7 @@
virtual GLenum getFormat(GLenum target, GLint level) const;
virtual GLenum getType(GLenum target, GLint level) const;
virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
- virtual int getLevelCount() const;
+ virtual int getTopLevel() const;
void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
@@ -179,7 +179,7 @@
virtual GLenum getFormat(GLenum target, GLint level) const;
virtual GLenum getType(GLenum target, GLint level) const;
virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
- virtual int getLevelCount() const;
+ virtual int getTopLevel() const;
void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
diff --git a/src/OpenGL/libGL/libGL.cpp b/src/OpenGL/libGL/libGL.cpp
index 171e520..87829be 100644
--- a/src/OpenGL/libGL/libGL.cpp
+++ b/src/OpenGL/libGL/libGL.cpp
@@ -802,10 +802,6 @@
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- if(!S3TC_SUPPORT)
- {
- return error(GL_INVALID_ENUM);
- }
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
@@ -931,10 +927,6 @@
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- if(!S3TC_SUPPORT)
- {
- return error(GL_INVALID_ENUM);
- }
break;
default:
return error(GL_INVALID_ENUM);
@@ -1101,14 +1093,7 @@
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- if(S3TC_SUPPORT)
- {
- return error(GL_INVALID_OPERATION);
- }
- else
- {
- return error(GL_INVALID_ENUM);
- }
+ return error(GL_INVALID_OPERATION);
default:
return error(GL_INVALID_ENUM);
}
@@ -3068,19 +3053,15 @@
"GL_EXT_texture_npot "
"GL_EXT_occlusion_query_boolean "
"GL_EXT_read_format_bgra "
- #if (S3TC_SUPPORT)
"GL_EXT_texture_compression_dxt1 "
- #endif
"GL_EXT_blend_func_separate "
"GL_EXT_secondary_color "
"GL_EXT_texture_filter_anisotropic "
"GL_EXT_texture_format_BGRA8888 "
"GL_EXT_framebuffer_blit "
"GL_EXT_framebuffer_multisample "
- #if (S3TC_SUPPORT)
"GL_EXT_texture_compression_dxt3 "
"GL_EXT_texture_compression_dxt5 "
- #endif
"GL_NV_fence";
default:
return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
@@ -4384,14 +4365,7 @@
format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
{
- if(S3TC_SUPPORT)
- {
- return error(GL_INVALID_OPERATION);
- }
- else
- {
- return error(GL_INVALID_ENUM);
- }
+ return error(GL_INVALID_OPERATION);
}
gl::Context *context = gl::getContext();
diff --git a/src/OpenGL/libGL/libGL.vcxproj b/src/OpenGL/libGL/libGL.vcxproj
index 415dcd8..ea8f5b5 100644
--- a/src/OpenGL/libGL/libGL.vcxproj
+++ b/src/OpenGL/libGL/libGL.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -30,41 +30,42 @@
<ProjectGuid>{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}</ProjectGuid>
<RootNamespace>libGL</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -153,6 +154,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BrowseInformation>true</BrowseInformation>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -179,6 +181,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BrowseInformation>true</BrowseInformation>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -212,6 +215,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -246,6 +250,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -280,6 +285,7 @@
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<WholeProgramOptimization>true</WholeProgramOptimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -312,6 +318,7 @@
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<WholeProgramOptimization>true</WholeProgramOptimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
diff --git a/src/OpenGL/libGL/main.cpp b/src/OpenGL/libGL/main.cpp
index 6a6e3da..5533321 100644
--- a/src/OpenGL/libGL/main.cpp
+++ b/src/OpenGL/libGL/main.cpp
@@ -36,12 +36,10 @@
{
TRACE("()");
- gl::Current *current = new gl::Current;
+ gl::Current *current = (gl::Current*)sw::Thread::allocateLocalStorage(currentTLS, sizeof(gl::Current));
if(current)
{
- sw::Thread::setLocalStorage(currentTLS, current);
-
current->context = nullptr;
current->display = nullptr;
current->drawSurface = nullptr;
@@ -55,8 +53,7 @@
wglMakeCurrent(NULL, NULL);
- delete (gl::Current*)sw::Thread::getLocalStorage(currentTLS);
- sw::Thread::setLocalStorage(currentTLS, nullptr);
+ sw::Thread::freeLocalStorage(currentTLS);
}
CONSTRUCTOR static bool glAttachProcess()
diff --git a/src/OpenGL/libGLES_CM/Android.mk b/src/OpenGL/libGLES_CM/Android.mk
index 7fa9070..9e68a53 100644
--- a/src/OpenGL/libGLES_CM/Android.mk
+++ b/src/OpenGL/libGLES_CM/Android.mk
@@ -86,8 +86,8 @@
endif
COMMON_LDFLAGS := \
+ -Wl,--version-script=$(LOCAL_PATH)/libGLES_CM.lds \
-Wl,--gc-sections \
- -Wl,--version-script=$(LOCAL_PATH)/exports.map \
-Wl,--hash-style=sysv
include $(CLEAR_VARS)
@@ -95,14 +95,10 @@
ifdef TARGET_2ND_ARCH
ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
LOCAL_MULTILIB := first
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
-else
-LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl
endif
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
endif
+LOCAL_MODULE_RELATIVE_PATH := egl
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_CLANG := true
LOCAL_SRC_FILES += $(COMMON_SRC_FILES)
@@ -119,14 +115,10 @@
ifdef TARGET_2ND_ARCH
ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
LOCAL_MULTILIB := first
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
-else
-LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl
endif
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
endif
+LOCAL_MODULE_RELATIVE_PATH := egl
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_CLANG := true
LOCAL_SRC_FILES += $(COMMON_SRC_FILES)
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index b6f76c8..31351b3 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -149,9 +149,14 @@
mTextureExternalZero = new TextureExternal(0);
mState.activeSampler = 0;
+
+ for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+ {
+ bindTexture((TextureType)type, 0);
+ }
+
bindArrayBuffer(0);
bindElementArrayBuffer(0);
- bindTexture2D(0);
bindFramebuffer(0);
bindRenderbuffer(0);
@@ -1012,18 +1017,11 @@
mState.elementArrayBuffer = getBuffer(buffer);
}
-void Context::bindTexture2D(GLuint texture)
+void Context::bindTexture(TextureType type, GLuint texture)
{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+ mResourceManager->checkTextureAllocation(texture, type);
- mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
-}
-
-void Context::bindTextureExternal(GLuint texture)
-{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
-
- mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
+ mState.samplerTexture[type][mState.activeSampler] = getTexture(texture);
}
void Context::bindFramebuffer(GLuint framebuffer)
@@ -1368,7 +1366,6 @@
}
break;
case GL_TEXTURE_BINDING_2D: *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name(); break;
- case GL_TEXTURE_BINDING_CUBE_MAP_OES: *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name(); break;
case GL_TEXTURE_BINDING_EXTERNAL_OES: *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name(); break;
case GL_MAX_LIGHTS: *params = MAX_LIGHTS; break;
case GL_MAX_MODELVIEW_STACK_DEPTH: *params = MAX_MODELVIEW_STACK_DEPTH; break;
@@ -2358,7 +2355,7 @@
if(baseTexture)
{
- int levelCount = baseTexture->getLevelCount();
+ int topLevel = baseTexture->getTopLevel();
if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
{
@@ -2372,9 +2369,9 @@
{
surfaceLevel = 0;
}
- else if(surfaceLevel >= levelCount)
+ else if(surfaceLevel > topLevel)
{
- surfaceLevel = levelCount - 1;
+ surfaceLevel = topLevel;
}
egl::Image *surface = texture->getImage(surfaceLevel);
@@ -2413,7 +2410,7 @@
}
}
- GLsizei outputPitch = egl::ComputePitch(width, format, type, mState.packAlignment);
+ GLsizei outputPitch = gl::ComputePitch(width, format, type, mState.packAlignment);
// Sized query sanity check
if(bufSize)
@@ -2435,7 +2432,7 @@
sw::Rect rect = {x, y, x + width, y + height};
rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
- unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
+ unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, 0, sw::LOCK_READONLY);
unsigned char *dest = (unsigned char*)pixels;
int inputPitch = (int)renderTarget->getPitch();
@@ -2444,12 +2441,12 @@
unsigned short *dest16 = (unsigned short*)dest;
unsigned int *dest32 = (unsigned int*)dest;
- if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&
+ if(renderTarget->getExternalFormat() == sw::FORMAT_A8B8G8R8 &&
format == GL_RGBA && type == GL_UNSIGNED_BYTE)
{
memcpy(dest, source, (rect.x1 - rect.x0) * 4);
}
- else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+ else if(renderTarget->getExternalFormat() == sw::FORMAT_A8R8G8B8 &&
format == GL_RGBA && type == GL_UNSIGNED_BYTE)
{
for(int i = 0; i < rect.x1 - rect.x0; i++)
@@ -2459,7 +2456,7 @@
dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
}
}
- else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
+ else if(renderTarget->getExternalFormat() == sw::FORMAT_X8R8G8B8 &&
format == GL_RGBA && type == GL_UNSIGNED_BYTE)
{
for(int i = 0; i < rect.x1 - rect.x0; i++)
@@ -2469,7 +2466,7 @@
dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
}
}
- else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
+ else if(renderTarget->getExternalFormat() == sw::FORMAT_X8R8G8B8 &&
format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
{
for(int i = 0; i < rect.x1 - rect.x0; i++)
@@ -2479,17 +2476,17 @@
dest32[i] = xrgb | 0xFF000000;
}
}
- else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
+ else if(renderTarget->getExternalFormat() == sw::FORMAT_A8R8G8B8 &&
format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
{
memcpy(dest, source, (rect.x1 - rect.x0) * 4);
}
- else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
+ else if(renderTarget->getExternalFormat() == sw::FORMAT_A1R5G5B5 &&
format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
{
memcpy(dest, source, (rect.x1 - rect.x0) * 2);
}
- else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
+ else if(renderTarget->getExternalFormat() == sw::FORMAT_R5G6B5 &&
format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5) // GL_BGR_EXT
{
memcpy(dest, source, (rect.x1 - rect.x0) * 2);
@@ -2503,7 +2500,7 @@
float b;
float a;
- switch(renderTarget->getInternalFormat())
+ switch(renderTarget->getExternalFormat())
{
case sw::FORMAT_R5G6B5:
{
@@ -2577,7 +2574,7 @@
break;
default:
UNIMPLEMENTED(); // FIXME
- UNREACHABLE(renderTarget->getInternalFormat());
+ UNREACHABLE(renderTarget->getExternalFormat());
}
switch(format)
@@ -2852,7 +2849,8 @@
void Context::blit(sw::Surface *source, const sw::SliceRect &sRect, sw::Surface *dest, const sw::SliceRect &dRect)
{
- device->blit(source, sRect, dest, dRect, false);
+ sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
+ device->blit(source, sRectF, dest, dRect, false);
}
void Context::finish()
@@ -3146,7 +3144,7 @@
return EGL_BAD_PARAMETER;
}
- if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
+ if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getTopLevel() == 0))
{
return EGL_BAD_PARAMETER;
}
diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h
index ece2860..7bf7791 100644
--- a/src/OpenGL/libGLES_CM/Context.h
+++ b/src/OpenGL/libGLES_CM/Context.h
@@ -79,10 +79,8 @@
const GLenum compressedTextureFormats[] =
{
GL_ETC1_RGB8_OES,
-#if (S3TC_SUPPORT)
GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
-#endif
};
const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
@@ -456,7 +454,7 @@
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
- void bindTexture2D(GLuint texture);
+ void bindTexture(TextureType type, GLuint texture);
void bindTextureExternal(GLuint texture);
void bindFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
diff --git a/src/OpenGL/libGLES_CM/Device.cpp b/src/OpenGL/libGLES_CM/Device.cpp
index 26f53bc..d1c3a04 100644
--- a/src/OpenGL/libGLES_CM/Device.cpp
+++ b/src/OpenGL/libGLES_CM/Device.cpp
@@ -217,69 +217,6 @@
stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
}
- egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
- {
- if(height > OUTLINE_RESOLUTION)
- {
- ERR("Invalid parameters: %dx%d", width, height);
- return nullptr;
- }
-
- bool lockable = true;
-
- switch(format)
- {
- // case FORMAT_D15S1:
- case FORMAT_D24S8:
- case FORMAT_D24X8:
- // case FORMAT_D24X4S4:
- case FORMAT_D24FS8:
- case FORMAT_D32:
- case FORMAT_D16:
- lockable = false;
- break;
- // case FORMAT_S8_LOCKABLE:
- // case FORMAT_D16_LOCKABLE:
- case FORMAT_D32F_LOCKABLE:
- // case FORMAT_D32_LOCKABLE:
- case FORMAT_DF24S8:
- case FORMAT_DF16S8:
- lockable = true;
- break;
- default:
- UNREACHABLE(format);
- }
-
- egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
-
- if(!surface)
- {
- ERR("Out of memory");
- return nullptr;
- }
-
- return surface;
- }
-
- egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)
- {
- if(height > OUTLINE_RESOLUTION)
- {
- ERR("Invalid parameters: %dx%d", width, height);
- return nullptr;
- }
-
- egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
-
- if(!surface)
- {
- ERR("Out of memory");
- return nullptr;
- }
-
- return surface;
- }
-
void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)
{
if(!bindResources() || !primitiveCount)
@@ -506,7 +443,8 @@
}
else
{
- blit(source, sRect, dest, dRect, scaling && filter);
+ sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
+ blit(source, sRectF, dest, dRect, scaling && filter);
}
return true;
diff --git a/src/OpenGL/libGLES_CM/Device.hpp b/src/OpenGL/libGLES_CM/Device.hpp
index c40e30d..ffabc45 100644
--- a/src/OpenGL/libGLES_CM/Device.hpp
+++ b/src/OpenGL/libGLES_CM/Device.hpp
@@ -49,8 +49,6 @@
void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
void clearDepth(float z);
void clearStencil(unsigned int stencil, unsigned int mask);
- egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
- egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);
void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount);
void drawPrimitive(sw::DrawType type, unsigned int primiveCount);
void setScissorEnable(bool enable);
diff --git a/src/OpenGL/libGLES_CM/Framebuffer.cpp b/src/OpenGL/libGLES_CM/Framebuffer.cpp
index 933aa2a..097c6a2 100644
--- a/src/OpenGL/libGLES_CM/Framebuffer.cpp
+++ b/src/OpenGL/libGLES_CM/Framebuffer.cpp
@@ -405,16 +405,16 @@
if(colorbuffer)
{
- switch(colorbuffer->getInternalFormat())
+ switch(colorbuffer->getFormat())
{
- case sw::FORMAT_A8R8G8B8: return GL_BGRA_EXT;
- case sw::FORMAT_A8B8G8R8: return GL_RGBA;
- case sw::FORMAT_X8R8G8B8: return GL_BGRA_EXT;
- case sw::FORMAT_X8B8G8R8: return GL_RGBA;
- case sw::FORMAT_A1R5G5B5: return GL_BGRA_EXT;
- case sw::FORMAT_R5G6B5: return GL_RGB;
+ case GL_BGRA8_EXT: return GL_BGRA_EXT;
+ case GL_RGBA4_OES: return GL_RGBA;
+ case GL_RGB5_A1_OES: return GL_RGBA;
+ case GL_RGBA8_OES: return GL_RGBA;
+ case GL_RGB565_OES: return GL_RGBA;
+ case GL_RGB8_OES: return GL_RGB;
default:
- UNREACHABLE(colorbuffer->getInternalFormat());
+ UNREACHABLE(colorbuffer->getFormat());
}
}
@@ -427,16 +427,16 @@
if(colorbuffer)
{
- switch(colorbuffer->getInternalFormat())
+ switch(colorbuffer->getFormat())
{
- case sw::FORMAT_A8R8G8B8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_A8B8G8R8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_X8R8G8B8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_X8B8G8R8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_A1R5G5B5: return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT;
- case sw::FORMAT_R5G6B5: return GL_UNSIGNED_SHORT_5_6_5;
+ case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE;
+ case GL_RGBA4_OES: return GL_UNSIGNED_SHORT_4_4_4_4;
+ case GL_RGB5_A1_OES: return GL_UNSIGNED_SHORT_5_5_5_1;
+ case GL_RGBA8_OES: return GL_UNSIGNED_BYTE;
+ case GL_RGB565_OES: return GL_UNSIGNED_SHORT_5_6_5;
+ case GL_RGB8_OES: return GL_UNSIGNED_BYTE;
default:
- UNREACHABLE(colorbuffer->getInternalFormat());
+ UNREACHABLE(colorbuffer->getFormat());
}
}
diff --git a/src/OpenGL/libGLES_CM/Renderbuffer.cpp b/src/OpenGL/libGLES_CM/Renderbuffer.cpp
index 96bf733..c832443 100644
--- a/src/OpenGL/libGLES_CM/Renderbuffer.cpp
+++ b/src/OpenGL/libGLES_CM/Renderbuffer.cpp
@@ -41,32 +41,32 @@
GLuint RenderbufferInterface::getRedSize() const
{
- return sw2es::GetRedSize(getInternalFormat());
+ return GetRedSize(getFormat());
}
GLuint RenderbufferInterface::getGreenSize() const
{
- return sw2es::GetGreenSize(getInternalFormat());
+ return GetGreenSize(getFormat());
}
GLuint RenderbufferInterface::getBlueSize() const
{
- return sw2es::GetBlueSize(getInternalFormat());
+ return GetBlueSize(getFormat());
}
GLuint RenderbufferInterface::getAlphaSize() const
{
- return sw2es::GetAlphaSize(getInternalFormat());
+ return GetAlphaSize(getFormat());
}
GLuint RenderbufferInterface::getDepthSize() const
{
- return sw2es::GetDepthSize(getInternalFormat());
+ return GetDepthSize(getFormat());
}
GLuint RenderbufferInterface::getStencilSize() const
{
- return sw2es::GetStencilSize(getInternalFormat());
+ return GetStencilSize(getFormat());
}
///// RenderbufferTexture2D Implementation ////////
@@ -122,16 +122,11 @@
return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
}
-GLenum RenderbufferTexture2D::getFormat() const
+GLint RenderbufferTexture2D::getFormat() const
{
return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
}
-sw::Format RenderbufferTexture2D::getInternalFormat() const
-{
- return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
-}
-
GLsizei RenderbufferTexture2D::getSamples() const
{
return 0;
@@ -200,11 +195,6 @@
return mInstance->getFormat();
}
-sw::Format Renderbuffer::getInternalFormat() const
-{
- return mInstance->getInternalFormat();
-}
-
GLuint Renderbuffer::getRedSize() const
{
return mInstance->getRedSize();
@@ -252,8 +242,7 @@
{
mWidth = 0;
mHeight = 0;
- format = GL_RGBA4_OES;
- internalFormat = sw::FORMAT_A8B8G8R8;
+ format = GL_NONE_OES;
mSamples = 0;
}
@@ -271,16 +260,11 @@
return mHeight;
}
-GLenum RenderbufferStorage::getFormat() const
+GLint RenderbufferStorage::getFormat() const
{
return format;
}
-sw::Format RenderbufferStorage::getInternalFormat() const
-{
- return internalFormat;
-}
-
GLsizei RenderbufferStorage::getSamples() const
{
return mSamples;
@@ -294,22 +278,24 @@
mWidth = renderTarget->getWidth();
mHeight = renderTarget->getHeight();
- internalFormat = renderTarget->getInternalFormat();
- format = sw2es::ConvertBackBufferFormat(internalFormat);
+ format = renderTarget->getFormat();
mSamples = renderTarget->getDepth() & ~1;
}
}
-Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
+Colorbuffer::Colorbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mRenderTarget(nullptr)
{
- Device *device = getDevice();
-
- sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
int supportedSamples = Context::getSupportedMultisampleCount(samples);
if(width > 0 && height > 0)
{
- mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
+ if(height > sw::OUTLINE_RESOLUTION)
+ {
+ error(GL_OUT_OF_MEMORY);
+ return;
+ }
+
+ mRenderTarget = egl::Image::create(width, height, internalformat, supportedSamples, false);
if(!mRenderTarget)
{
@@ -320,8 +306,7 @@
mWidth = width;
mHeight = height;
- this->format = format;
- internalFormat = requestedFormat;
+ format = internalformat;
mSamples = supportedSamples;
}
@@ -371,21 +356,24 @@
mWidth = depthStencil->getWidth();
mHeight = depthStencil->getHeight();
- internalFormat = depthStencil->getInternalFormat();
- format = sw2es::ConvertDepthStencilFormat(internalFormat);
+ format = depthStencil->getFormat();
mSamples = depthStencil->getDepth() & ~1;
}
}
-DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
+DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mDepthStencil(nullptr)
{
- Device *device = getDevice();
-
int supportedSamples = Context::getSupportedMultisampleCount(samples);
if(width > 0 && height > 0)
{
- mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
+ if(height > sw::OUTLINE_RESOLUTION)
+ {
+ error(GL_OUT_OF_MEMORY);
+ return;
+ }
+
+ mDepthStencil = egl::Image::create(width, height, internalformat, supportedSamples, false);
if(!mDepthStencil)
{
@@ -396,8 +384,7 @@
mWidth = width;
mHeight = height;
- format = GL_DEPTH24_STENCIL8_OES;
- internalFormat = sw::FORMAT_D24S8;
+ format = internalformat;
mSamples = supportedSamples;
}
@@ -441,22 +428,10 @@
Depthbuffer::Depthbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
{
- if(depthStencil)
- {
- format = GL_DEPTH_COMPONENT16_OES; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
- }
}
-Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
+Depthbuffer::Depthbuffer(int width, int height, GLenum internalformat, GLsizei samples) : DepthStencilbuffer(width, height, internalformat, samples)
{
- if(mDepthStencil)
- {
- format = GL_DEPTH_COMPONENT16_OES; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
- }
}
Depthbuffer::~Depthbuffer()
@@ -465,22 +440,10 @@
Stencilbuffer::Stencilbuffer(egl::Image *depthStencil) : DepthStencilbuffer(depthStencil)
{
- if(depthStencil)
- {
- format = GL_STENCIL_INDEX8_OES; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
- }
}
-Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
+Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, GL_STENCIL_INDEX8_OES, samples)
{
- if(mDepthStencil)
- {
- format = GL_STENCIL_INDEX8_OES; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
- }
}
Stencilbuffer::~Stencilbuffer()
diff --git a/src/OpenGL/libGLES_CM/Renderbuffer.h b/src/OpenGL/libGLES_CM/Renderbuffer.h
index 6bb462f..4405b93 100644
--- a/src/OpenGL/libGLES_CM/Renderbuffer.h
+++ b/src/OpenGL/libGLES_CM/Renderbuffer.h
@@ -48,8 +48,7 @@
virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0;
- virtual GLenum getFormat() const = 0;
- virtual sw::Format getInternalFormat() const = 0;
+ virtual GLint getFormat() const = 0;
virtual GLsizei getSamples() const = 0;
GLuint getRedSize() const;
@@ -76,8 +75,7 @@
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
- virtual GLenum getFormat() const;
- virtual sw::Format getInternalFormat() const;
+ virtual GLint getFormat() const;
virtual GLsizei getSamples() const;
private:
@@ -100,15 +98,13 @@
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
- virtual GLenum getFormat() const;
- virtual sw::Format getInternalFormat() const;
+ virtual GLint getFormat() const;
virtual GLsizei getSamples() const;
protected:
GLsizei mWidth;
GLsizei mHeight;
GLenum format;
- sw::Format internalFormat;
GLsizei mSamples;
};
@@ -136,7 +132,6 @@
GLsizei getWidth() const;
GLsizei getHeight() const;
GLenum getFormat() const;
- sw::Format getInternalFormat() const;
GLuint getRedSize() const;
GLuint getGreenSize() const;
GLuint getBlueSize() const;
@@ -155,7 +150,7 @@
{
public:
explicit Colorbuffer(egl::Image *renderTarget);
- Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+ Colorbuffer(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
virtual ~Colorbuffer();
@@ -171,7 +166,7 @@
{
public:
explicit DepthStencilbuffer(egl::Image *depthStencil);
- DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+ DepthStencilbuffer(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
~DepthStencilbuffer();
@@ -187,7 +182,7 @@
{
public:
explicit Depthbuffer(egl::Image *depthStencil);
- Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);
+ Depthbuffer(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
virtual ~Depthbuffer();
};
diff --git a/src/OpenGL/libGLES_CM/ResourceManager.h b/src/OpenGL/libGLES_CM/ResourceManager.h
index 7520580..24953e8 100644
--- a/src/OpenGL/libGLES_CM/ResourceManager.h
+++ b/src/OpenGL/libGLES_CM/ResourceManager.h
@@ -33,7 +33,6 @@
enum TextureType
{
TEXTURE_2D,
- TEXTURE_CUBE,
TEXTURE_EXTERNAL,
TEXTURE_TYPE_COUNT,
diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index 80a3886..05f1ebd 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -227,51 +227,36 @@
return image;
}
-void Texture::setImage(egl::Context *context, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)
+void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)
{
if(pixels && image)
{
- egl::Image::UnpackInfo unpackInfo;
- unpackInfo.alignment = unpackAlignment;
- image->loadImageData(context, 0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackInfo, pixels);
+ gl::PixelStorageModes unpackParameters;
+ unpackParameters.alignment = unpackAlignment;
+ image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackParameters, pixels);
}
}
void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)
{
- if(pixels && image)
+ if(pixels && image && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
{
image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);
}
}
-void Texture::subImage(egl::Context *context, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)
+void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image)
{
if(!image)
{
return error(GL_INVALID_OPERATION);
}
- if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
- {
- return error(GL_INVALID_VALUE);
- }
-
- if(IsCompressed(image->getFormat()))
- {
- return error(GL_INVALID_OPERATION);
- }
-
- if(format != image->getFormat())
- {
- return error(GL_INVALID_OPERATION);
- }
-
if(pixels)
{
- egl::Image::UnpackInfo unpackInfo;
- unpackInfo.alignment = unpackAlignment;
- image->loadImageData(context, xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels);
+ gl::PixelStorageModes unpackParameters;
+ unpackParameters.alignment = unpackAlignment;
+ image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackParameters, pixels);
}
}
@@ -282,17 +267,7 @@
return error(GL_INVALID_OPERATION);
}
- if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
- {
- return error(GL_INVALID_VALUE);
- }
-
- if(format != image->getFormat())
- {
- return error(GL_INVALID_OPERATION);
- }
-
- if(pixels)
+ if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
{
image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);
}
@@ -426,68 +401,44 @@
return image[level] ? image[level]->getHeight() : 0;
}
-GLenum Texture2D::getFormat(GLenum target, GLint level) const
+GLint Texture2D::getFormat(GLenum target, GLint level) const
{
ASSERT(target == GL_TEXTURE_2D);
return image[level] ? image[level]->getFormat() : GL_NONE;
}
-GLenum Texture2D::getType(GLenum target, GLint level) const
-{
- ASSERT(target == GL_TEXTURE_2D);
- return image[level] ? image[level]->getType() : GL_NONE;
-}
-
-sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const
-{
- ASSERT(target == GL_TEXTURE_2D);
- return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
-}
-
-int Texture2D::getLevelCount() const
+int Texture2D::getTopLevel() const
{
ASSERT(isSamplerComplete());
- int levels = 0;
+ int level = 0;
- while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+ while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
{
- levels++;
+ level++;
}
- return levels;
+ return level - 1;
}
-void Texture2D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
if(image[level])
{
image[level]->release();
}
- image[level] = egl::Image::create(this, width, height, format, type);
+ image[level] = egl::Image::create(this, width, height, internalformat);
if(!image[level])
{
return error(GL_OUT_OF_MEMORY);
}
- Texture::setImage(context, format, type, unpackAlignment, pixels, image[level]);
+ Texture::setImage(format, type, unpackAlignment, pixels, image[level]);
}
void Texture2D::bindTexImage(gl::Surface *surface)
{
- switch(surface->getInternalFormat())
- {
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- break;
- default:
- UNIMPLEMENTED();
- return;
- }
-
for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
if(image[level])
@@ -522,7 +473,7 @@
image[level]->release();
}
- image[level] = egl::Image::create(this, width, height, format, GL_UNSIGNED_BYTE);
+ image[level] = egl::Image::create(this, width, height, format);
if(!image[level])
{
@@ -532,9 +483,9 @@
Texture::setCompressedImage(imageSize, pixels, image[level]);
}
-void Texture2D::subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::subImage(context, xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);
+ Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);
}
void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
@@ -557,7 +508,7 @@
image[level]->release();
}
- image[level] = egl::Image::create(this, width, height, format, GL_UNSIGNED_BYTE);
+ image[level] = egl::Image::create(this, width, height, format);
if(!image[level])
{
@@ -662,11 +613,6 @@
return false;
}
- if(image[level]->getType() != image[0]->getType())
- {
- return false;
- }
-
if(image[level]->getWidth() != std::max(1, width >> level))
{
return false;
@@ -707,7 +653,7 @@
image[i]->release();
}
- image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
+ image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat());
if(!image[i])
{
@@ -720,10 +666,10 @@
void Texture2D::autoGenerateMipmaps()
{
- if(generateMipmap && image[0]->hasDirtyMipmaps())
+ if(generateMipmap && image[0]->hasDirtyContents())
{
generateMipmaps();
- image[0]->cleanMipmaps();
+ image[0]->markContentsClean();
}
}
@@ -805,7 +751,9 @@
return nullptr;
}
- return egl::Image::create(width, height, format, multiSampleDepth, false);
+ GLenum internalformat = sw2es::ConvertBackBufferFormat(format);
+
+ return egl::Image::create(width, height, internalformat, multiSampleDepth, false);
}
egl::Image *createDepthStencil(int width, int height, sw::Format format, int multiSampleDepth)
@@ -841,7 +789,9 @@
UNREACHABLE(format);
}
- egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
+ GLenum internalformat = sw2es::ConvertDepthStencilFormat(format);
+
+ egl::Image *surface = egl::Image::create(width, height, internalformat, multiSampleDepth, lockable);
if(!surface)
{
diff --git a/src/OpenGL/libGLES_CM/Texture.h b/src/OpenGL/libGLES_CM/Texture.h
index c99c1dc..0439039 100644
--- a/src/OpenGL/libGLES_CM/Texture.h
+++ b/src/OpenGL/libGLES_CM/Texture.h
@@ -76,10 +76,8 @@
virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
- virtual GLenum getFormat(GLenum target, GLint level) const = 0;
- virtual GLenum getType(GLenum target, GLint level) const = 0;
- virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
- virtual int getLevelCount() const = 0;
+ virtual GLint getFormat(GLenum target, GLint level) const = 0;
+ virtual int getTopLevel() const = 0;
virtual bool isSamplerComplete() const = 0;
virtual bool isCompressed(GLenum target, GLint level) const = 0;
@@ -98,8 +96,8 @@
protected:
~Texture() override;
- void setImage(egl::Context *context, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
- void subImage(egl::Context *context, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
+ void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
+ void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);
void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);
@@ -134,14 +132,12 @@
GLsizei getWidth(GLenum target, GLint level) const override;
GLsizei getHeight(GLenum target, GLint level) const override;
- GLenum getFormat(GLenum target, GLint level) const override;
- GLenum getType(GLenum target, GLint level) const override;
- sw::Format getInternalFormat(GLenum target, GLint level) const override;
- int getLevelCount() const override;
+ GLint getFormat(GLenum target, GLint level) const override;
+ int getTopLevel() const override;
- void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
- void subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, 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);
void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
index 62acae1..e717d60 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -32,6 +32,7 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
+#include <algorithm>
#include <limits>
namespace es1
@@ -47,41 +48,6 @@
return true;
}
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es1::Texture *texture)
-{
- if(!texture)
- {
- return error(GL_INVALID_OPERATION, false);
- }
-
- if(compressed != texture->isCompressed(target, level))
- {
- return error(GL_INVALID_OPERATION, false);
- }
-
- if(format != GL_NONE_OES && format != texture->getFormat(target, level))
- {
- return error(GL_INVALID_OPERATION, false);
- }
-
- if(compressed)
- {
- if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
- (height % 4 != 0 && height != texture->getHeight(target, 0)))
- {
- return error(GL_INVALID_OPERATION, false);
- }
- }
-
- if(xoffset + width > texture->getWidth(target, level) ||
- yoffset + height > texture->getHeight(target, level))
- {
- return error(GL_INVALID_VALUE, false);
- }
-
- return true;
-}
-
void ActiveTexture(GLenum texture)
{
TRACE("(GLenum texture = 0x%X)", texture);
@@ -200,15 +166,9 @@
if(context)
{
- if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))
- {
- // [OpenGL ES 2.0.25] Section 4.4.3 page 112
- // [OpenGL ES 3.0.2] Section 4.4.2 page 201
- // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
- // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
- return error(GL_INVALID_OPERATION);
- }
-
+ // [GL_EXT_framebuffer_object]
+ // If <renderbuffer> is not zero, then the resulting renderbuffer object
+ // is a new state vector, initialized with a zero-sized memory buffer
context->bindRenderbuffer(renderbuffer);
}
}
@@ -231,11 +191,11 @@
switch(target)
{
case GL_TEXTURE_2D:
- context->bindTexture2D(texture);
- return;
+ context->bindTexture(TEXTURE_2D, texture);
+ break;
case GL_TEXTURE_EXTERNAL_OES:
- context->bindTextureExternal(texture);
- return;
+ context->bindTexture(TEXTURE_EXTERNAL, texture);
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -720,16 +680,10 @@
switch(internalformat)
{
case GL_ETC1_RGB8_OES:
- break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- if(!S3TC_SUPPORT)
- {
- return error(GL_INVALID_ENUM);
- }
break;
case GL_DEPTH_COMPONENT16_OES:
- case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_STENCIL_OES:
case GL_DEPTH24_STENCIL8_OES:
return error(GL_INVALID_OPERATION);
@@ -759,7 +713,7 @@
return error(GL_INVALID_ENUM);
}
- if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
+ if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
{
return error(GL_INVALID_VALUE);
}
@@ -805,13 +759,8 @@
switch(format)
{
case GL_ETC1_RGB8_OES:
- break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- if(!S3TC_SUPPORT)
- {
- return error(GL_INVALID_ENUM);
- }
break;
default:
return error(GL_INVALID_ENUM);
@@ -826,7 +775,7 @@
if(context)
{
- if(imageSize != egl::ComputeCompressedSize(width, height, format))
+ if(imageSize != gl::ComputeCompressedSize(width, height, format))
{
return error(GL_INVALID_VALUE);
}
@@ -841,10 +790,13 @@
{
es1::Texture2D *texture = context->getTexture2D();
- if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
+ GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE_OES, texture);
+ if(validationError != GL_NO_ERROR)
{
- texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+ return error(validationError);
}
+
+ texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
}
else UNREACHABLE(target);
}
@@ -898,7 +850,7 @@
es1::Renderbuffer *source = framebuffer->getColorbuffer();
GLenum colorbufferFormat = source->getFormat();
- // [OpenGL ES 2.0.24] table 3.9
+ // [OpenGL ES 1.1.12] table 3.9
switch(internalformat)
{
case GL_ALPHA:
@@ -929,27 +881,38 @@
if(colorbufferFormat != GL_RGBA &&
colorbufferFormat != GL_RGBA4_OES &&
colorbufferFormat != GL_RGB5_A1_OES &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGRA_EXT && // GL_EXT_texture_format_BGRA8888
+ colorbufferFormat != GL_BGRA8_EXT) // GL_EXT_texture_format_BGRA8888
{
return error(GL_INVALID_OPERATION);
}
break;
case GL_ETC1_RGB8_OES:
- return error(GL_INVALID_OPERATION);
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- if(S3TC_SUPPORT)
- {
- return error(GL_INVALID_OPERATION);
- }
- else
- {
- return error(GL_INVALID_ENUM);
- }
+ return error(GL_INVALID_OPERATION);
+ case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 doesn't mention the format to be accepted by glCopyTexImage2D.
default:
return error(GL_INVALID_ENUM);
}
+ // Determine the sized internal format.
+ if(gl::GetBaseInternalFormat(colorbufferFormat) == internalformat)
+ {
+ internalformat = colorbufferFormat;
+ }
+ else if(GetRedSize(colorbufferFormat) == 8)
+ {
+ internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_BYTE);
+ }
+ else
+ {
+ UNIMPLEMENTED();
+
+ return error(GL_INVALID_OPERATION);
+ }
+
if(target == GL_TEXTURE_2D)
{
es1::Texture2D *texture = context->getTexture2D();
@@ -1023,9 +986,10 @@
}
else UNREACHABLE(target);
- if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE_OES, texture))
+ GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE_OES, GL_NONE_OES, texture);
+ if(validationError != GL_NO_ERROR)
{
- return;
+ return error(validationError);
}
texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
@@ -1877,7 +1841,12 @@
{
case GL_RENDERBUFFER_WIDTH_OES: *params = renderbuffer->getWidth(); break;
case GL_RENDERBUFFER_HEIGHT_OES: *params = renderbuffer->getHeight(); break;
- case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: *params = renderbuffer->getFormat(); break;
+ case GL_RENDERBUFFER_INTERNAL_FORMAT_OES:
+ {
+ GLint internalformat = renderbuffer->getFormat();
+ *params = (internalformat == GL_NONE_OES) ? GL_RGBA4_OES : internalformat;
+ }
+ break;
case GL_RENDERBUFFER_RED_SIZE_OES: *params = renderbuffer->getRedSize(); break;
case GL_RENDERBUFFER_GREEN_SIZE_OES: *params = renderbuffer->getGreenSize(); break;
case GL_RENDERBUFFER_BLUE_SIZE_OES: *params = renderbuffer->getBlueSize(); break;
@@ -2285,7 +2254,6 @@
"GL_OES_blend_func_separate "
"GL_OES_blend_subtract "
"GL_OES_compressed_ETC1_RGB8_texture "
- "GL_OES_depth_texture "
"GL_OES_EGL_image "
"GL_OES_EGL_image_external "
"GL_OES_EGL_sync "
@@ -2300,11 +2268,9 @@
"GL_OES_texture_npot "
"GL_EXT_blend_minmax "
"GL_EXT_read_format_bgra "
- #if (S3TC_SUPPORT)
"GL_EXT_texture_compression_dxt1 "
"GL_ANGLE_texture_compression_dxt3 "
"GL_ANGLE_texture_compression_dxt5 "
- #endif
"GL_EXT_texture_filter_anisotropic "
"GL_EXT_texture_format_BGRA8888";
default:
@@ -3444,9 +3410,6 @@
switch(internalformat)
{
- case GL_DEPTH_COMPONENT16_OES:
- context->setRenderbufferStorage(new es1::Depthbuffer(width, height, 0));
- break;
case GL_RGBA4_OES:
case GL_RGB5_A1_OES:
case GL_RGB565_OES:
@@ -3454,11 +3417,14 @@
case GL_RGBA8_OES:
context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));
break;
+ case GL_DEPTH_COMPONENT16_OES:
+ context->setRenderbufferStorage(new es1::Depthbuffer(width, height, internalformat, 0));
+ break;
case GL_STENCIL_INDEX8_OES:
context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));
break;
case GL_DEPTH24_STENCIL8_OES:
- context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, 0));
+ context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, internalformat, 0));
break;
default:
return error(GL_INVALID_ENUM);
@@ -4226,7 +4192,6 @@
switch(type)
{
case GL_UNSIGNED_BYTE:
- case GL_FLOAT:
break;
default:
return error(GL_INVALID_ENUM);
@@ -4237,7 +4202,6 @@
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_6_5:
- case GL_FLOAT:
break;
default:
return error(GL_INVALID_ENUM);
@@ -4249,7 +4213,6 @@
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_FLOAT:
break;
default:
return error(GL_INVALID_ENUM);
@@ -4265,17 +4228,9 @@
}
break;
case GL_ETC1_RGB8_OES:
- return error(GL_INVALID_OPERATION);
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- if(S3TC_SUPPORT)
- {
- return error(GL_INVALID_OPERATION);
- }
- else
- {
- return error(GL_INVALID_ENUM);
- }
+ return error(GL_INVALID_OPERATION);
case GL_DEPTH_STENCIL_OES:
switch(type)
{
@@ -4294,6 +4249,8 @@
return error(GL_INVALID_VALUE);
}
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
+
es1::Context *context = es1::getContext();
if(context)
@@ -4320,7 +4277,7 @@
return error(GL_INVALID_OPERATION);
}
- texture->setImage(context, level, width, height, format, type, context->getUnpackAlignment(), pixels);
+ texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackAlignment(), pixels);
}
else UNREACHABLE(target);
}
@@ -4537,11 +4494,6 @@
return error(GL_INVALID_VALUE);
}
- if(!es1::CheckTextureFormatType(format, type))
- {
- return error(GL_INVALID_ENUM);
- }
-
if(width == 0 || height == 0 || !pixels)
{
return;
@@ -4555,10 +4507,13 @@
{
es1::Texture2D *texture = context->getTexture2D();
- if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
+ GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture);
+ if(validationError != GL_NO_ERROR)
{
- texture->subImage(context, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
+ return error(validationError);
}
+
+ texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else UNREACHABLE(target);
}
@@ -4727,46 +4682,215 @@
extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)
{
- struct Extension
+ struct Function
{
const char *name;
__eglMustCastToProperFunctionPointerType address;
};
- static const Extension glExtensions[] =
+ struct CompareFunctor
{
- #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
-
- EXTENSION(glEGLImageTargetTexture2DOES),
- EXTENSION(glEGLImageTargetRenderbufferStorageOES),
- EXTENSION(glIsRenderbufferOES),
- EXTENSION(glBindRenderbufferOES),
- EXTENSION(glDeleteRenderbuffersOES),
- EXTENSION(glGenRenderbuffersOES),
- EXTENSION(glRenderbufferStorageOES),
- EXTENSION(glGetRenderbufferParameterivOES),
- EXTENSION(glIsFramebufferOES),
- EXTENSION(glBindFramebufferOES),
- EXTENSION(glDeleteFramebuffersOES),
- EXTENSION(glGenFramebuffersOES),
- EXTENSION(glCheckFramebufferStatusOES),
- EXTENSION(glFramebufferRenderbufferOES),
- EXTENSION(glFramebufferTexture2DOES),
- EXTENSION(glGetFramebufferAttachmentParameterivOES),
- EXTENSION(glGenerateMipmapOES),
- EXTENSION(glBlendEquationOES),
- EXTENSION(glBlendEquationSeparateOES),
- EXTENSION(glBlendFuncSeparateOES),
- EXTENSION(glPointSizePointerOES),
-
- #undef EXTENSION
+ bool operator()(const Function &a, const Function &b) const
+ {
+ return strcmp(a.name, b.name) < 0;
+ }
};
- for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
+ // This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
+ // The Unix command "LC_COLLATE=C sort" will generate the correct order.
+ static const Function glFunctions[] =
{
- if(strcmp(procname, glExtensions[ext].name) == 0)
+ #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
+
+ FUNCTION(glActiveTexture),
+ FUNCTION(glAlphaFunc),
+ FUNCTION(glAlphaFuncx),
+ FUNCTION(glBindBuffer),
+ FUNCTION(glBindFramebufferOES),
+ FUNCTION(glBindRenderbufferOES),
+ FUNCTION(glBindTexture),
+ FUNCTION(glBlendEquationOES),
+ FUNCTION(glBlendEquationSeparateOES),
+ FUNCTION(glBlendFunc),
+ FUNCTION(glBlendFuncSeparateOES),
+ FUNCTION(glBufferData),
+ FUNCTION(glBufferSubData),
+ FUNCTION(glCheckFramebufferStatusOES),
+ FUNCTION(glClear),
+ FUNCTION(glClearColor),
+ FUNCTION(glClearColorx),
+ FUNCTION(glClearDepthf),
+ FUNCTION(glClearDepthx),
+ FUNCTION(glClearStencil),
+ FUNCTION(glClientActiveTexture),
+ FUNCTION(glClipPlanef),
+ FUNCTION(glClipPlanex),
+ FUNCTION(glColor4f),
+ FUNCTION(glColor4ub),
+ FUNCTION(glColor4x),
+ FUNCTION(glColorMask),
+ FUNCTION(glColorPointer),
+ FUNCTION(glCompressedTexImage2D),
+ FUNCTION(glCompressedTexSubImage2D),
+ FUNCTION(glCopyTexImage2D),
+ FUNCTION(glCopyTexSubImage2D),
+ FUNCTION(glCullFace),
+ FUNCTION(glDeleteBuffers),
+ FUNCTION(glDeleteFramebuffersOES),
+ FUNCTION(glDeleteRenderbuffersOES),
+ FUNCTION(glDeleteTextures),
+ FUNCTION(glDepthFunc),
+ FUNCTION(glDepthMask),
+ FUNCTION(glDepthRangef),
+ FUNCTION(glDepthRangex),
+ FUNCTION(glDisable),
+ FUNCTION(glDisableClientState),
+ FUNCTION(glDrawArrays),
+ FUNCTION(glDrawElements),
+ FUNCTION(glDrawTexfOES),
+ FUNCTION(glDrawTexfvOES),
+ FUNCTION(glDrawTexiOES),
+ FUNCTION(glDrawTexivOES),
+ FUNCTION(glDrawTexsOES),
+ FUNCTION(glDrawTexsvOES),
+ FUNCTION(glDrawTexxOES),
+ FUNCTION(glDrawTexxvOES),
+ FUNCTION(glEGLImageTargetRenderbufferStorageOES),
+ FUNCTION(glEGLImageTargetTexture2DOES),
+ FUNCTION(glEnable),
+ FUNCTION(glEnableClientState),
+ FUNCTION(glFinish),
+ FUNCTION(glFlush),
+ FUNCTION(glFogf),
+ FUNCTION(glFogfv),
+ FUNCTION(glFogx),
+ FUNCTION(glFogxv),
+ FUNCTION(glFramebufferRenderbufferOES),
+ FUNCTION(glFramebufferTexture2DOES),
+ FUNCTION(glFrontFace),
+ FUNCTION(glFrustumf),
+ FUNCTION(glFrustumx),
+ FUNCTION(glGenBuffers),
+ FUNCTION(glGenFramebuffersOES),
+ FUNCTION(glGenRenderbuffersOES),
+ FUNCTION(glGenTextures),
+ FUNCTION(glGenerateMipmapOES),
+ FUNCTION(glGetBooleanv),
+ FUNCTION(glGetBufferParameteriv),
+ FUNCTION(glGetClipPlanef),
+ FUNCTION(glGetClipPlanex),
+ FUNCTION(glGetError),
+ FUNCTION(glGetFixedv),
+ FUNCTION(glGetFloatv),
+ FUNCTION(glGetFramebufferAttachmentParameterivOES),
+ FUNCTION(glGetIntegerv),
+ FUNCTION(glGetLightfv),
+ FUNCTION(glGetLightxv),
+ FUNCTION(glGetMaterialfv),
+ FUNCTION(glGetMaterialxv),
+ FUNCTION(glGetPointerv),
+ FUNCTION(glGetRenderbufferParameterivOES),
+ FUNCTION(glGetString),
+ FUNCTION(glGetTexEnvfv),
+ FUNCTION(glGetTexEnviv),
+ FUNCTION(glGetTexEnvxv),
+ FUNCTION(glGetTexParameterfv),
+ FUNCTION(glGetTexParameteriv),
+ FUNCTION(glGetTexParameterxv),
+ FUNCTION(glHint),
+ FUNCTION(glIsBuffer),
+ FUNCTION(glIsEnabled),
+ FUNCTION(glIsFramebufferOES),
+ FUNCTION(glIsRenderbufferOES),
+ FUNCTION(glIsTexture),
+ FUNCTION(glLightModelf),
+ FUNCTION(glLightModelfv),
+ FUNCTION(glLightModelx),
+ FUNCTION(glLightModelxv),
+ FUNCTION(glLightf),
+ FUNCTION(glLightfv),
+ FUNCTION(glLightx),
+ FUNCTION(glLightxv),
+ FUNCTION(glLineWidth),
+ FUNCTION(glLineWidthx),
+ FUNCTION(glLoadIdentity),
+ FUNCTION(glLoadMatrixf),
+ FUNCTION(glLoadMatrixx),
+ FUNCTION(glLogicOp),
+ FUNCTION(glMaterialf),
+ FUNCTION(glMaterialfv),
+ FUNCTION(glMaterialx),
+ FUNCTION(glMaterialxv),
+ FUNCTION(glMatrixMode),
+ FUNCTION(glMultMatrixf),
+ FUNCTION(glMultMatrixx),
+ FUNCTION(glMultiTexCoord4f),
+ FUNCTION(glMultiTexCoord4x),
+ FUNCTION(glNormal3f),
+ FUNCTION(glNormal3x),
+ FUNCTION(glNormalPointer),
+ FUNCTION(glOrthof),
+ FUNCTION(glOrthox),
+ FUNCTION(glPixelStorei),
+ FUNCTION(glPointParameterf),
+ FUNCTION(glPointParameterfv),
+ FUNCTION(glPointParameterx),
+ FUNCTION(glPointParameterxv),
+ FUNCTION(glPointSize),
+ FUNCTION(glPointSizePointerOES),
+ FUNCTION(glPointSizex),
+ FUNCTION(glPolygonOffset),
+ FUNCTION(glPolygonOffsetx),
+ FUNCTION(glPopMatrix),
+ FUNCTION(glPushMatrix),
+ FUNCTION(glReadPixels),
+ FUNCTION(glRenderbufferStorageOES),
+ FUNCTION(glRotatef),
+ FUNCTION(glRotatex),
+ FUNCTION(glSampleCoverage),
+ FUNCTION(glSampleCoveragex),
+ FUNCTION(glScalef),
+ FUNCTION(glScalex),
+ FUNCTION(glScissor),
+ FUNCTION(glShadeModel),
+ FUNCTION(glStencilFunc),
+ FUNCTION(glStencilMask),
+ FUNCTION(glStencilOp),
+ FUNCTION(glTexCoordPointer),
+ FUNCTION(glTexEnvf),
+ FUNCTION(glTexEnvfv),
+ FUNCTION(glTexEnvi),
+ FUNCTION(glTexEnviv),
+ FUNCTION(glTexEnvx),
+ FUNCTION(glTexEnvxv),
+ FUNCTION(glTexImage2D),
+ FUNCTION(glTexParameterf),
+ FUNCTION(glTexParameterfv),
+ FUNCTION(glTexParameteri),
+ FUNCTION(glTexParameteriv),
+ FUNCTION(glTexParameterx),
+ FUNCTION(glTexParameterxv),
+ FUNCTION(glTexSubImage2D),
+ FUNCTION(glTranslatef),
+ FUNCTION(glTranslatex),
+ FUNCTION(glVertexPointer),
+ FUNCTION(glViewport),
+
+ #undef FUNCTION
+ };
+
+ static const size_t numFunctions = sizeof glFunctions / sizeof(Function);
+ static const Function *const glFunctionsEnd = glFunctions + numFunctions;
+
+ Function needle;
+ needle.name = procname;
+
+ if(procname && strncmp("gl", procname, 2) == 0)
+ {
+ const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor());
+ if(result != glFunctionsEnd && strcmp(procname, result->name) == 0)
{
- return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
+ return (__eglMustCastToProperFunctionPointerType)result->address;
}
}
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.hpp b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
index 5a3a289..cd9447e 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.hpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
@@ -279,6 +279,8 @@
#else
const char *libGLES_CM_lib[] = {"libGLES_CM_translator.dylib", "libGLES_CM.dylib"};
#endif
+ #elif defined(__Fuchsia__)
+ const char *libGLES_CM_lib[] = {"libGLES_CM.so"};
#else
#error "libGLES_CM::loadExports unimplemented for this platform"
#endif
diff --git a/src/OpenGL/libGLES_CM/exports.map b/src/OpenGL/libGLES_CM/libGLES_CM.lds
similarity index 100%
rename from src/OpenGL/libGLES_CM/exports.map
rename to src/OpenGL/libGLES_CM/libGLES_CM.lds
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj b/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj
index 7d2a496..fec59e6 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -30,41 +30,42 @@
<ProjectGuid>{235B1D85-E6B6-45E2-BA5D-5C60396428FF}</ProjectGuid>
<RootNamespace>libGLES_CM</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -124,7 +125,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>$(SolutionDir)\src;$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;EGLAPI=;GL_API=;GL_APICALL=;GL_GLEXT_PROTOTYPES;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -135,6 +136,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BrowseInformation>true</BrowseInformation>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -153,7 +155,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>$(SolutionDir)\src;$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;EGLAPI=;GL_API=;GL_APICALL=;GL_GLEXT_PROTOTYPES;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@@ -163,6 +165,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BrowseInformation>true</BrowseInformation>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -198,6 +201,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -234,6 +238,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -270,6 +275,7 @@
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<WholeProgramOptimization>true</WholeProgramOptimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -304,6 +310,7 @@
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<WholeProgramOptimization>true</WholeProgramOptimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
diff --git a/src/OpenGL/libGLES_CM/utilities.cpp b/src/OpenGL/libGLES_CM/utilities.cpp
index b0b110a..0df34c7 100644
--- a/src/OpenGL/libGLES_CM/utilities.cpp
+++ b/src/OpenGL/libGLES_CM/utilities.cpp
@@ -32,6 +32,72 @@
format == GL_ETC1_RGB8_OES;
}
+ bool IsSizedInternalFormat(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_ALPHA8_EXT:
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ case GL_LUMINANCE8_EXT:
+ case GL_RGBA4_OES:
+ case GL_RGB5_A1_OES:
+ case GL_RGB565_OES:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ case GL_BGRA8_EXT: // GL_APPLE_texture_format_BGRA8888
+ case GL_DEPTH_COMPONENT16_OES:
+ case GL_STENCIL_INDEX8_OES:
+ case GL_DEPTH24_STENCIL8_OES:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture)
+ {
+ if(!texture)
+ {
+ return GL_INVALID_OPERATION;
+ }
+
+ GLenum sizedInternalFormat = texture->getFormat(target, level);
+
+ if(compressed)
+ {
+ if(format != sizedInternalFormat)
+ {
+ return GL_INVALID_OPERATION;
+ }
+ }
+ else if(!copy) // CopyTexSubImage doesn't have format/type parameters.
+ {
+ GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target);
+ if(validationError != GL_NO_ERROR)
+ {
+ return validationError;
+ }
+ }
+
+ if(compressed)
+ {
+ if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
+ (height % 4 != 0 && height != texture->getHeight(target, 0)))
+ {
+ return GL_INVALID_OPERATION;
+ }
+ }
+
+ if(xoffset + width > texture->getWidth(target, level) ||
+ yoffset + height > texture->getHeight(target, level))
+ {
+ return GL_INVALID_VALUE;
+ }
+
+ return GL_NO_ERROR;
+ }
+
bool IsDepthTexture(GLenum format)
{
return format == GL_DEPTH_STENCIL_OES;
@@ -68,120 +134,366 @@
}
// Verify that format/type are one of the combinations from table 3.4.
- bool CheckTextureFormatType(GLenum format, GLenum type)
+ GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target)
{
switch(type)
{
case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_INT_24_8_OES: // GL_OES_packed_depth_stencil
+ break;
+ default:
+ return GL_INVALID_ENUM;
+ }
+
+ switch(format)
+ {
+ case GL_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
+ break;
+ case GL_DEPTH_STENCIL_OES: // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
+ switch(target)
+ {
+ case GL_TEXTURE_2D:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ default:
+ return GL_INVALID_ENUM;
+ }
+
+ if((GLenum)internalformat != format)
+ {
+ if(gl::IsUnsizedInternalFormat(internalformat))
+ {
+ return GL_INVALID_OPERATION;
+ }
+
+ if(!IsSizedInternalFormat(internalformat))
+ {
+ return GL_INVALID_VALUE;
+ }
+ }
+
+ if((GLenum)internalformat == format)
+ {
+ // Validate format, type, and unsized internalformat combinations [OpenGL ES 1.1 Table 3.3]
switch(format)
{
case GL_RGBA:
- case GL_BGRA_EXT:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
case GL_RGB:
- case GL_ALPHA:
- case GL_LUMINANCE:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
case GL_LUMINANCE_ALPHA:
- return true;
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ switch(type)
+ {
+ case GL_UNSIGNED_INT_24_8_OES: // GL_OES_packed_depth_stencil
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_BGRA_EXT:
+ if(type != GL_UNSIGNED_BYTE) // GL_APPLE_texture_format_BGRA8888 / GL_EXT_texture_format_BGRA8888
+ {
+ return GL_INVALID_OPERATION;
+ }
+ break;
default:
- return false;
+ UNREACHABLE(format);
+ return GL_INVALID_ENUM;
}
- case GL_FLOAT:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- return (format == GL_RGBA);
- case GL_UNSIGNED_SHORT_5_6_5:
- return (format == GL_RGB);
- case GL_UNSIGNED_INT_24_8_OES:
- return (format == GL_DEPTH_STENCIL_OES);
- default:
- return false;
- }
- }
- bool IsColorRenderable(GLenum internalformat)
- {
- switch(internalformat)
+ return GL_NO_ERROR;
+ }
+
+ // Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
+ bool validSizedInternalformat = false;
+ #define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
+
+ switch(format)
{
- case GL_RGB:
case GL_RGBA:
- case GL_RGBA4_OES:
- case GL_RGB5_A1_OES:
- case GL_RGB565_OES:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
- return true;
- case GL_DEPTH_COMPONENT16_OES:
- case GL_STENCIL_INDEX8_OES:
- case GL_DEPTH24_STENCIL8_OES:
- return false;
- default:
- UNIMPLEMENTED();
- }
-
- return false;
- }
-
- bool IsDepthRenderable(GLenum internalformat)
- {
- switch(internalformat)
- {
- case GL_DEPTH_COMPONENT16_OES:
- case GL_DEPTH24_STENCIL8_OES:
- return true;
- case GL_STENCIL_INDEX8_OES:
- case GL_RGBA4_OES:
- case GL_RGB5_A1_OES:
- case GL_RGB565_OES:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
- return false;
- default:
- UNIMPLEMENTED();
- }
-
- return false;
- }
-
- bool IsStencilRenderable(GLenum internalformat)
- {
- switch(internalformat)
- {
- case GL_STENCIL_INDEX8_OES:
- case GL_DEPTH24_STENCIL8_OES:
- return true;
- case GL_RGBA4_OES:
- case GL_RGB5_A1_OES:
- case GL_RGB565_OES:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
- case GL_DEPTH_COMPONENT16_OES:
- return false;
- default:
- UNIMPLEMENTED();
- }
-
- return false;
- }
-
- bool IsAlpha(GLenum texFormat)
- {
- switch(texFormat)
- {
- case GL_ALPHA:
- return true;
- default:
- return false;
- }
- }
-
- bool IsRGB(GLenum texFormat)
- {
- switch(texFormat)
- {
- case GL_LUMINANCE:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8_OES, GL_RGB5_A1_OES, GL_RGBA4_OES)
+ case GL_UNSIGNED_SHORT_4_4_4_4: VALIDATE_INTERNALFORMAT(GL_RGBA4_OES)
+ case GL_UNSIGNED_SHORT_5_5_5_1: VALIDATE_INTERNALFORMAT(GL_RGB5_A1_OES)
+ default: return GL_INVALID_OPERATION;
+ }
+ break;
case GL_RGB:
- case GL_RGB565_OES: // GL_OES_framebuffer_object
- case GL_RGB8_OES: // GL_OES_rgb8_rgba8
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8_OES, GL_RGB565_OES)
+ case GL_UNSIGNED_SHORT_5_6_5: VALIDATE_INTERNALFORMAT(GL_RGB565_OES)
+ default: return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ switch(type)
+ {
+ case GL_UNSIGNED_INT_24_8_OES: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8_OES)
+ default: return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT)
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_LUMINANCE:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT)
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT)
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_BGRA_EXT: // GL_APPLE_texture_format_BGRA8888
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_BGRA8_EXT)
+ default: return GL_INVALID_OPERATION;
+ }
+ break;
+ default:
+ UNREACHABLE(format);
+ return GL_INVALID_ENUM;
+ }
+
+ #undef VALIDATE_INTERNALFORMAT
+
+ if(!validSizedInternalformat)
+ {
+ return GL_INVALID_OPERATION;
+ }
+
+ return GL_NO_ERROR;
+ }
+
+ bool IsColorRenderable(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_RGBA4_OES:
+ case GL_RGB5_A1_OES:
+ case GL_RGB565_OES:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ return true;
+ case GL_DEPTH_COMPONENT16_OES:
+ case GL_STENCIL_INDEX8_OES:
+ case GL_DEPTH24_STENCIL8_OES:
+ return false;
+ default:
+ UNIMPLEMENTED();
+ }
+
+ return false;
+ }
+
+ bool IsDepthRenderable(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_DEPTH_COMPONENT16_OES:
+ case GL_DEPTH24_STENCIL8_OES:
+ return true;
+ case GL_STENCIL_INDEX8_OES:
+ case GL_RGBA4_OES:
+ case GL_RGB5_A1_OES:
+ case GL_RGB565_OES:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ return false;
+ default:
+ UNIMPLEMENTED();
+ }
+
+ return false;
+ }
+
+ bool IsStencilRenderable(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_STENCIL_INDEX8_OES:
+ case GL_DEPTH24_STENCIL8_OES:
+ return true;
+ case GL_RGBA4_OES:
+ case GL_RGB5_A1_OES:
+ case GL_RGB565_OES:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ case GL_DEPTH_COMPONENT16_OES:
+ return false;
+ default:
+ UNIMPLEMENTED();
+ }
+
+ return false;
+ }
+
+ GLuint GetAlphaSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_NONE_OES: return 0;
+ case GL_RGBA4_OES: return 4;
+ case GL_RGB5_A1_OES: return 1;
+ case GL_RGB565_OES: return 0;
+ case GL_RGB8_OES: return 0;
+ case GL_RGBA8_OES: return 8;
+ case GL_BGRA8_EXT: return 8;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetRedSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_NONE_OES: return 0;
+ case GL_RGBA4_OES: return 4;
+ case GL_RGB5_A1_OES: return 5;
+ case GL_RGB565_OES: return 5;
+ case GL_RGB8_OES: return 8;
+ case GL_RGBA8_OES: return 8;
+ case GL_BGRA8_EXT: return 8;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetGreenSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_NONE_OES: return 0;
+ case GL_RGBA4_OES: return 4;
+ case GL_RGB5_A1_OES: return 5;
+ case GL_RGB565_OES: return 6;
+ case GL_RGB8_OES: return 8;
+ case GL_RGBA8_OES: return 8;
+ case GL_BGRA8_EXT: return 8;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetBlueSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_NONE_OES: return 0;
+ case GL_RGBA4_OES: return 4;
+ case GL_RGB5_A1_OES: return 5;
+ case GL_RGB565_OES: return 5;
+ case GL_RGB8_OES: return 8;
+ case GL_RGBA8_OES: return 8;
+ case GL_BGRA8_EXT: return 8;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetDepthSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_STENCIL_INDEX8_OES: return 0;
+ case GL_DEPTH_COMPONENT16_OES: return 16;
+ case GL_DEPTH24_STENCIL8_OES: return 24;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetStencilSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_STENCIL_INDEX8_OES: return 8;
+ case GL_DEPTH_COMPONENT16_OES: return 0;
+ case GL_DEPTH24_STENCIL8_OES: return 8;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ bool IsAlpha(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_ALPHA8_EXT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool IsRGB(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_LUMINANCE8_EXT:
+ case GL_RGB565_OES:
+ case GL_RGB8_OES:
case SW_YV12_BT601:
case SW_YV12_BT709:
case SW_YV12_JFIF:
@@ -191,16 +503,16 @@
}
}
- bool IsRGBA(GLenum texFormat)
+ bool IsRGBA(GLint internalformat)
{
- switch(texFormat)
+ switch(internalformat)
{
- case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE8_ALPHA8_EXT:
case GL_RGBA:
- case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
- case GL_RGBA4_OES: // GL_OES_framebuffer_object
- case GL_RGB5_A1_OES: // GL_OES_framebuffer_object
- case GL_RGBA8_OES: // GL_OES_rgb8_rgba8
+ case GL_BGRA8_EXT: // GL_EXT_texture_format_BGRA8888
+ case GL_RGBA4_OES:
+ case GL_RGB5_A1_OES:
+ case GL_RGBA8_OES:
return true;
default:
return false;
@@ -478,7 +790,7 @@
sw::DrawType elementSize;
switch(elementType)
{
- case GL_NONE: elementSize = sw::DRAW_NONINDEXED; break;
+ case GL_NONE_OES: elementSize = sw::DRAW_NONINDEXED; break;
case GL_UNSIGNED_BYTE: elementSize = sw::DRAW_INDEXED8; break;
case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16; break;
case GL_UNSIGNED_INT: elementSize = sw::DRAW_INDEXED32; break;
@@ -490,22 +802,6 @@
return true;
}
- sw::Format ConvertRenderbufferFormat(GLenum format)
- {
- switch(format)
- {
- case GL_RGBA4_OES:
- case GL_RGB5_A1_OES:
- case GL_RGBA8_OES: return sw::FORMAT_A8B8G8R8;
- case GL_RGB565_OES: return sw::FORMAT_R5G6B5;
- case GL_RGB8_OES: return sw::FORMAT_X8B8G8R8;
- case GL_DEPTH_COMPONENT16_OES:
- case GL_STENCIL_INDEX8_OES:
- case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
- default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;
- }
- }
-
sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation)
{
switch(operation)
@@ -549,145 +845,6 @@
namespace sw2es
{
- unsigned int GetStencilSize(sw::Format stencilFormat)
- {
- switch(stencilFormat)
- {
- case sw::FORMAT_D24FS8:
- case sw::FORMAT_D24S8:
- case sw::FORMAT_D32FS8_TEXTURE:
- return 8;
- // case sw::FORMAT_D24X4S4:
- // return 4;
- // case sw::FORMAT_D15S1:
- // return 1;
- // case sw::FORMAT_D16_LOCKABLE:
- case sw::FORMAT_D32:
- case sw::FORMAT_D24X8:
- case sw::FORMAT_D32F_LOCKABLE:
- case sw::FORMAT_D16:
- return 0;
- // case sw::FORMAT_D32_LOCKABLE: return 0;
- // case sw::FORMAT_S8_LOCKABLE: return 8;
- default:
- return 0;
- }
- }
-
- unsigned int GetAlphaSize(sw::Format colorFormat)
- {
- switch(colorFormat)
- {
- case sw::FORMAT_A16B16G16R16F:
- return 16;
- case sw::FORMAT_A32B32G32R32F:
- return 32;
- case sw::FORMAT_A2R10G10B10:
- return 2;
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- return 8;
- case sw::FORMAT_A1R5G5B5:
- return 1;
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- case sw::FORMAT_R5G6B5:
- return 0;
- default:
- return 0;
- }
- }
-
- unsigned int GetRedSize(sw::Format colorFormat)
- {
- switch(colorFormat)
- {
- case sw::FORMAT_A16B16G16R16F:
- return 16;
- case sw::FORMAT_A32B32G32R32F:
- return 32;
- case sw::FORMAT_A2R10G10B10:
- return 10;
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- return 8;
- case sw::FORMAT_A1R5G5B5:
- case sw::FORMAT_R5G6B5:
- return 5;
- default:
- return 0;
- }
- }
-
- unsigned int GetGreenSize(sw::Format colorFormat)
- {
- switch(colorFormat)
- {
- case sw::FORMAT_A16B16G16R16F:
- return 16;
- case sw::FORMAT_A32B32G32R32F:
- return 32;
- case sw::FORMAT_A2R10G10B10:
- return 10;
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- return 8;
- case sw::FORMAT_A1R5G5B5:
- return 5;
- case sw::FORMAT_R5G6B5:
- return 6;
- default:
- return 0;
- }
- }
-
- unsigned int GetBlueSize(sw::Format colorFormat)
- {
- switch(colorFormat)
- {
- case sw::FORMAT_A16B16G16R16F:
- return 16;
- case sw::FORMAT_A32B32G32R32F:
- return 32;
- case sw::FORMAT_A2R10G10B10:
- return 10;
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- return 8;
- case sw::FORMAT_A1R5G5B5:
- case sw::FORMAT_R5G6B5:
- return 5;
- default:
- return 0;
- }
- }
-
- unsigned int GetDepthSize(sw::Format depthFormat)
- {
- switch(depthFormat)
- {
- // case sw::FORMAT_D16_LOCKABLE: return 16;
- case sw::FORMAT_D32: return 32;
- // case sw::FORMAT_D15S1: return 15;
- case sw::FORMAT_D24S8: return 24;
- case sw::FORMAT_D24X8: return 24;
- // case sw::FORMAT_D24X4S4: return 24;
- case sw::FORMAT_D16: return 16;
- case sw::FORMAT_D32F_LOCKABLE: return 32;
- case sw::FORMAT_D24FS8: return 24;
- // case sw::FORMAT_D32_LOCKABLE: return 32;
- // case sw::FORMAT_S8_LOCKABLE: return 0;
- case sw::FORMAT_D32FS8_TEXTURE: return 32;
- default: return 0;
- }
- }
-
GLenum ConvertBackBufferFormat(sw::Format format)
{
switch(format)
diff --git a/src/OpenGL/libGLES_CM/utilities.h b/src/OpenGL/libGLES_CM/utilities.h
index ec2a257..402a341 100644
--- a/src/OpenGL/libGLES_CM/utilities.h
+++ b/src/OpenGL/libGLES_CM/utilities.h
@@ -31,20 +31,29 @@
struct Color;
bool IsCompressed(GLenum format);
+ GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture);
bool IsDepthTexture(GLenum format);
bool IsStencilTexture(GLenum format);
bool IsCubemapTextureTarget(GLenum target);
int CubeFaceIndex(GLenum cubeTarget);
bool IsTextureTarget(GLenum target);
- bool CheckTextureFormatType(GLenum format, GLenum type);
+ GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target);
- bool IsColorRenderable(GLenum internalformat);
- bool IsDepthRenderable(GLenum internalformat);
- bool IsStencilRenderable(GLenum internalformat);
+ bool IsColorRenderable(GLint internalformat);
+ bool IsDepthRenderable(GLint internalformat);
+ bool IsStencilRenderable(GLint internalformat);
- bool IsAlpha(GLenum texFormat);
- bool IsRGB(GLenum texFormat);
- bool IsRGBA(GLenum texFormat);
+ GLuint GetAlphaSize(GLint internalformat);
+ GLuint GetRedSize(GLint internalformat);
+ GLuint GetGreenSize(GLint internalformat);
+ GLuint GetBlueSize(GLint internalformat);
+ GLuint GetDepthSize(GLint internalformat);
+ GLuint GetStencilSize(GLint internalformat);
+
+ bool IsAlpha(GLint texFormat);
+ bool IsRGB(GLint texFormat);
+ bool IsRGBA(GLint texFormat);
}
namespace es2sw
@@ -63,7 +72,6 @@
sw::MipmapType ConvertMipMapFilter(GLenum minFilter);
sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &swPrimitiveType, int &primitiveCount);
- sw::Format ConvertRenderbufferFormat(GLenum format);
sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation);
sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument);
sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand);
@@ -71,13 +79,6 @@
namespace sw2es
{
- GLuint GetAlphaSize(sw::Format colorFormat);
- GLuint GetRedSize(sw::Format colorFormat);
- GLuint GetGreenSize(sw::Format colorFormat);
- GLuint GetBlueSize(sw::Format colorFormat);
- GLuint GetDepthSize(sw::Format depthFormat);
- GLuint GetStencilSize(sw::Format stencilFormat);
-
GLenum ConvertBackBufferFormat(sw::Format format);
GLenum ConvertDepthStencilFormat(sw::Format format);
}
diff --git a/src/OpenGL/libGLESv2/Android.mk b/src/OpenGL/libGLESv2/Android.mk
index 5b020cb..94e8089 100644
--- a/src/OpenGL/libGLESv2/Android.mk
+++ b/src/OpenGL/libGLESv2/Android.mk
@@ -41,6 +41,7 @@
libGLESv2.cpp \
libGLESv3.cpp \
main.cpp \
+ entry_points.cpp \
Program.cpp \
Query.cpp \
Renderbuffer.cpp \
@@ -94,8 +95,8 @@
endif
COMMON_LDFLAGS := \
+ -Wl,--version-script=$(LOCAL_PATH)/libGLESv2.lds \
-Wl,--gc-sections \
- -Wl,--version-script=$(LOCAL_PATH)/exports.map \
-Wl,--hash-style=sysv
include $(CLEAR_VARS)
@@ -103,14 +104,10 @@
ifdef TARGET_2ND_ARCH
ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
LOCAL_MULTILIB := first
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
-else
-LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl
endif
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
endif
+LOCAL_MODULE_RELATIVE_PATH := egl
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_CLANG := true
LOCAL_SRC_FILES += $(COMMON_SRC_FILES)
@@ -127,14 +124,10 @@
ifdef TARGET_2ND_ARCH
ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
LOCAL_MULTILIB := first
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
-else
-LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl
endif
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/egl
endif
+LOCAL_MODULE_RELATIVE_PATH := egl
+LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_CLANG := true
LOCAL_SRC_FILES += $(COMMON_SRC_FILES)
diff --git a/src/OpenGL/libGLESv2/BUILD.gn b/src/OpenGL/libGLESv2/BUILD.gn
index a917cfd..b4383c9 100644
--- a/src/OpenGL/libGLESv2/BUILD.gn
+++ b/src/OpenGL/libGLESv2/BUILD.gn
@@ -50,17 +50,11 @@
}
}
-swiftshader_shared_library("swiftshader_libGLESv2") {
- if (!is_mac) {
- output_name = "libGLESv2"
- output_dir = "$root_out_dir/swiftshader"
- }
-
+swiftshader_static_library("swiftshader_libGLESv2_static") {
deps = [
"../../OpenGL/compiler:swiftshader_opengl_compiler",
"../../Reactor:swiftshader_reactor",
"../../Renderer:swiftshader_renderer",
- "//build/config:exe_and_shlib_deps",
]
sources = [
@@ -80,21 +74,45 @@
"VertexArray.cpp",
"VertexDataManager.cpp",
"libGLESv2.cpp",
- "libGLESv2.def",
- "libGLESv2.rc",
"libGLESv3.cpp",
"main.cpp",
"resource.h",
"utilities.cpp",
]
+ configs = [ ":swiftshader_libGLESv2_private_config" ]
+
+ include_dirs = [
+ "../../../include",
+ "../..",
+ "..",
+ ]
+}
+
+swiftshader_shared_library("swiftshader_libGLESv2") {
+ if (!is_mac) {
+ output_name = "libGLESv2"
+ output_dir = "$root_out_dir/swiftshader"
+ }
+
+ deps = [
+ ":swiftshader_libGLESv2_static",
+ "//build/config:exe_and_shlib_deps",
+ ]
+
+ sources = [
+ "entry_points.cpp",
+ "libGLESv2.def",
+ "libGLESv2.rc",
+ ]
+
if (is_win) {
ldflags = [ "/DEF:" + rebase_path("libGLESv2.def", root_build_dir) ]
} else if (is_mac) {
ldflags = [ "-Wl,-install_name,@rpath/libswiftshader_libGLESv2.dylib" ]
} else if (is_linux) {
ldflags =
- [ "-Wl,--version-script=" + rebase_path("exports.map", root_build_dir) ]
+ [ "-Wl,--version-script=" + rebase_path("libGLESv2.lds", root_build_dir) ]
}
configs = [ ":swiftshader_libGLESv2_private_config" ]
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 6ca3c81..f495e8a 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
Binary files differ
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index d00f545..a9c5259 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -53,6 +53,7 @@
class Texture3D;
class Texture2DArray;
class TextureCubeMap;
+class Texture2DRect;
class TextureExternal;
class Framebuffer;
class Renderbuffer;
@@ -102,19 +103,17 @@
MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = MAX_VERTEX_UNIFORM_BLOCKS_COMPONENTS + MAX_VERTEX_UNIFORM_COMPONENTS,
MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4,
MAX_UNIFORM_BUFFER_BINDINGS = sw::MAX_UNIFORM_BUFFER_BINDINGS,
- UNIFORM_BUFFER_OFFSET_ALIGNMENT = 1,
+ UNIFORM_BUFFER_OFFSET_ALIGNMENT = 4,
NUM_PROGRAM_BINARY_FORMATS = 0,
};
const GLenum compressedTextureFormats[] =
{
GL_ETC1_RGB8_OES,
-#if (S3TC_SUPPORT)
GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
-#endif
#if (GL_ES_VERSION_3_0)
GL_COMPRESSED_R11_EAC,
GL_COMPRESSED_SIGNED_R11_EAC,
@@ -126,6 +125,7 @@
GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
GL_COMPRESSED_RGBA8_ETC2_EAC,
GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
+#if (ASTC_SUPPORT)
GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
@@ -154,7 +154,8 @@
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
-#endif
+#endif // ASTC_SUPPORT
+#endif // GL_ES_VERSION_3_0
};
const GLenum GL_TEXTURE_FILTERING_HINT_CHROMIUM = 0x8AF0;
@@ -192,7 +193,7 @@
class VertexAttribute
{
public:
- VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mDivisor(0), mPointer(nullptr), mArrayEnabled(false)
+ VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mPureInteger(false), mStride(0), mDivisor(0), mPointer(nullptr), mArrayEnabled(false)
{
mCurrentValue[0].f = 0.0f;
mCurrentValue[1].f = 0.0f;
@@ -299,6 +300,7 @@
GLenum mType;
GLint mSize;
bool mNormalized;
+ bool mPureInteger;
GLsizei mStride; // 0 means natural stride
GLuint mDivisor; // From glVertexAttribDivisor
@@ -420,13 +422,8 @@
gl::BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS];
gl::BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
- egl::Image::UnpackInfo unpackInfo;
- GLint packAlignment;
- GLint packRowLength;
- GLint packImageHeight;
- GLint packSkipPixels;
- GLint packSkipRows;
- GLint packSkipImages;
+ gl::PixelStorageModes unpackParameters;
+ gl::PixelStorageModes packParameters;
};
class [[clang::lto_visibility_public]] Context : public egl::Context
@@ -513,7 +510,6 @@
void setFramebufferReadBuffer(GLenum buf);
void setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs);
- GLuint getReadFramebufferColorIndex() const;
GLuint getActiveQuery(GLenum target) const;
@@ -524,7 +520,7 @@
void setVertexAttribDivisor(unsigned int attribNum, GLuint divisor);
const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
- bool normalized, GLsizei stride, const void *pointer);
+ bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
const VertexAttributeArray &getVertexArrayAttributes();
@@ -537,14 +533,12 @@
void setUnpackSkipPixels(GLint skipPixels);
void setUnpackSkipRows(GLint skipRows);
void setUnpackSkipImages(GLint skipImages);
- const egl::Image::UnpackInfo& getUnpackInfo() const;
+ const gl::PixelStorageModes &getUnpackParameters() const;
void setPackAlignment(GLint alignment);
void setPackRowLength(GLint rowLength);
- void setPackImageHeight(GLint imageHeight);
void setPackSkipPixels(GLint skipPixels);
void setPackSkipRows(GLint skipRows);
- void setPackSkipImages(GLint skipImages);
// These create and destroy methods are merely pass-throughs to
// ResourceManager, which owns these object types
@@ -591,11 +585,7 @@
void bindPixelPackBuffer(GLuint buffer);
void bindPixelUnpackBuffer(GLuint buffer);
void bindTransformFeedbackBuffer(GLuint buffer);
- void bindTexture2D(GLuint texture);
- void bindTextureCubeMap(GLuint texture);
- void bindTextureExternal(GLuint texture);
- void bindTexture3D(GLuint texture);
- void bindTexture2DArray(GLuint texture);
+ void bindTexture(TextureType type, GLuint texture);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
@@ -632,6 +622,7 @@
VertexArray *getCurrentVertexArray() const;
bool isVertexArray(GLuint array) const;
TransformFeedback *getTransformFeedback(GLuint transformFeedback) const;
+ bool isTransformFeedback(GLuint transformFeedback) const;
TransformFeedback *getTransformFeedback() const;
Sampler *getSampler(GLuint sampler) const;
bool isSampler(GLuint sampler) const;
@@ -643,13 +634,16 @@
Buffer *getPixelPackBuffer() const;
Buffer *getPixelUnpackBuffer() const;
Buffer *getGenericUniformBuffer() const;
- const GLvoid* getPixels(const GLvoid* data) const;
+ GLsizei getRequiredBufferSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type) const;
+ GLenum getPixels(const GLvoid **data, GLenum type, GLsizei imageSize) const;
bool getBuffer(GLenum target, es2::Buffer **buffer) const;
Program *getCurrentProgram() const;
Texture2D *getTexture2D() const;
+ Texture2D *getTexture2D(GLenum target) const;
Texture3D *getTexture3D() const;
Texture2DArray *getTexture2DArray() const;
TextureCubeMap *getTextureCubeMap() const;
+ Texture2DRect *getTexture2DRect() const;
TextureExternal *getTextureExternal() const;
Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
Framebuffer *getReadFramebuffer() const;
@@ -739,6 +733,7 @@
gl::BindingPointer<Texture3D> mTexture3DZero;
gl::BindingPointer<Texture2DArray> mTexture2DArrayZero;
gl::BindingPointer<TextureCubeMap> mTextureCubeMapZero;
+ gl::BindingPointer<Texture2DRect> mTexture2DRectZero;
gl::BindingPointer<TextureExternal> mTextureExternalZero;
gl::NameSpace<Framebuffer> mFramebufferNameSpace;
diff --git a/src/OpenGL/libGLESv2/Device.cpp b/src/OpenGL/libGLESv2/Device.cpp
index a4ba15a..6fcfba8 100644
--- a/src/OpenGL/libGLESv2/Device.cpp
+++ b/src/OpenGL/libGLESv2/Device.cpp
@@ -249,73 +249,6 @@
stencilBuffer->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
}
- egl::Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
- {
- if(height > OUTLINE_RESOLUTION)
- {
- ERR("Invalid parameters: %dx%d", width, height);
- return nullptr;
- }
-
- bool lockable = true;
-
- switch(format)
- {
- // case FORMAT_D15S1:
- case FORMAT_D24S8:
- case FORMAT_D24X8:
- // case FORMAT_D24X4S4:
- case FORMAT_D24FS8:
- case FORMAT_D32:
- case FORMAT_D16:
- case FORMAT_D32F:
- case FORMAT_D32F_COMPLEMENTARY:
- lockable = false;
- break;
- // case FORMAT_S8_LOCKABLE:
- // case FORMAT_D16_LOCKABLE:
- case FORMAT_D32F_LOCKABLE:
- // case FORMAT_D32_LOCKABLE:
- case FORMAT_DF24S8:
- case FORMAT_DF16S8:
- case FORMAT_D32FS8_TEXTURE:
- case FORMAT_D32FS8_SHADOW:
- lockable = true;
- break;
- default:
- UNREACHABLE(format);
- }
-
- egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
-
- if(!surface)
- {
- ERR("Out of memory");
- return nullptr;
- }
-
- return surface;
- }
-
- egl::Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)
- {
- if(height > OUTLINE_RESOLUTION)
- {
- ERR("Invalid parameters: %dx%d", width, height);
- return nullptr;
- }
-
- egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
-
- if(!surface)
- {
- ERR("Out of memory");
- return nullptr;
- }
-
- return surface;
- }
-
void Device::drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount)
{
if(!bindResources() || !primitiveCount)
@@ -363,7 +296,7 @@
scissorEnable = enable;
}
- void Device::setRenderTarget(int index, egl::Image *renderTarget)
+ void Device::setRenderTarget(int index, egl::Image *renderTarget, unsigned int layer)
{
if(renderTarget)
{
@@ -377,10 +310,10 @@
this->renderTarget[index] = renderTarget;
- Renderer::setRenderTarget(index, renderTarget);
+ Renderer::setRenderTarget(index, renderTarget, layer);
}
- void Device::setDepthBuffer(egl::Image *depthBuffer)
+ void Device::setDepthBuffer(egl::Image *depthBuffer, unsigned int layer)
{
if(this->depthBuffer == depthBuffer)
{
@@ -399,10 +332,10 @@
this->depthBuffer = depthBuffer;
- Renderer::setDepthBuffer(depthBuffer);
+ Renderer::setDepthBuffer(depthBuffer, layer);
}
- void Device::setStencilBuffer(egl::Image *stencilBuffer)
+ void Device::setStencilBuffer(egl::Image *stencilBuffer, unsigned int layer)
{
if(this->stencilBuffer == stencilBuffer)
{
@@ -421,7 +354,7 @@
this->stencilBuffer = stencilBuffer;
- Renderer::setStencilBuffer(stencilBuffer);
+ Renderer::setStencilBuffer(stencilBuffer, layer);
}
void Device::setScissorRect(const sw::Rect &rect)
@@ -454,7 +387,7 @@
this->viewport = viewport;
}
- void Device::copyBuffer(sw::byte *sourceBuffer, sw::byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY)
+ void Device::copyBuffer(byte *sourceBuffer, byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY)
{
if(flipX)
{
@@ -463,8 +396,8 @@
sourceBuffer += (height - 1) * sourcePitch;
for(unsigned int y = 0; y < height; ++y, sourceBuffer -= sourcePitch, destBuffer += destPitch)
{
- sw::byte *srcX = sourceBuffer + (width - 1) * bytes;
- sw::byte *dstX = destBuffer;
+ byte *srcX = sourceBuffer + (width - 1) * bytes;
+ byte *dstX = destBuffer;
for(unsigned int x = 0; x < width; ++x, dstX += bytes, srcX -= bytes)
{
memcpy(dstX, srcX, bytes);
@@ -475,8 +408,8 @@
{
for(unsigned int y = 0; y < height; ++y, sourceBuffer += sourcePitch, destBuffer += destPitch)
{
- sw::byte *srcX = sourceBuffer + (width - 1) * bytes;
- sw::byte *dstX = destBuffer;
+ byte *srcX = sourceBuffer + (width - 1) * bytes;
+ byte *dstX = destBuffer;
for(unsigned int x = 0; x < width; ++x, dstX += bytes, srcX -= bytes)
{
memcpy(dstX, srcX, bytes);
@@ -506,7 +439,7 @@
}
}
- bool Device::stretchRect(sw::Surface *source, const sw::SliceRect *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, unsigned char flags)
+ bool Device::stretchRect(sw::Surface *source, const sw::SliceRectF *sourceRect, sw::Surface *dest, const sw::SliceRect *destRect, unsigned char flags)
{
if(!source || !dest)
{
@@ -537,12 +470,16 @@
flipY = (destRect->y0 > destRect->y1);
}
- SliceRect sRect;
+ SliceRectF sRect;
SliceRect dRect;
if(sourceRect)
{
- sRect = *sourceRect;
+ sRect.x0 = sourceRect->x0;
+ sRect.x1 = sourceRect->x1;
+ sRect.y0 = sourceRect->y0;
+ sRect.y1 = sourceRect->y1;
+ sRect.slice = sourceRect->slice;
if(sRect.x0 > sRect.x1)
{
@@ -556,10 +493,10 @@
}
else
{
- sRect.y0 = 0;
- sRect.x0 = 0;
- sRect.y1 = sHeight;
- sRect.x1 = sWidth;
+ sRect.y0 = 0.0f;
+ sRect.x0 = 0.0f;
+ sRect.y1 = (float)sHeight;
+ sRect.x1 = (float)sWidth;
}
if(destRect)
@@ -584,21 +521,47 @@
dRect.x1 = dWidth;
}
+ sw::Rect srcClipRect(0, 0, sWidth, sHeight);
+ ClipSrcRect(sRect, dRect, srcClipRect, flipX, flipY);
+
+ sw::Rect dstClipRect(0, 0, dWidth, dHeight);
+ ClipDstRect(sRect, dRect, dstClipRect, flipX, flipY);
+
+ if((sRect.width() == 0) || (sRect.height() == 0) ||
+ (dRect.width() == 0) || (dRect.height() == 0))
+ {
+ return true; // no work to do
+ }
+
if(!validRectangle(&sRect, source) || !validRectangle(&dRect, dest))
{
ERR("Invalid parameters");
return false;
}
- bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
+ bool isDepth = (flags & Device::DEPTH_BUFFER) && Surface::isDepth(source->getInternalFormat());
+ bool isStencil = (flags & Device::STENCIL_BUFFER) && Surface::isStencil(source->getInternalFormat());
+ bool isColor = (flags & Device::COLOR_BUFFER) == Device::COLOR_BUFFER;
+
+ if(!isColor && !isDepth && !isStencil)
+ {
+ return true;
+ }
+
+ int sourceSliceB = isStencil ? source->getStencilSliceB() : source->getInternalSliceB();
+ int destSliceB = isStencil ? dest->getStencilSliceB() : dest->getInternalSliceB();
+ int sourcePitchB = isStencil ? source->getStencilPitchB() : source->getInternalPitchB();
+ int destPitchB = isStencil ? dest->getStencilPitchB() : dest->getInternalPitchB();
+
+ bool isOutOfBounds = (sRect.x0 < 0.0f) || (sRect.y0 < 0.0f) || (sRect.x1 > (float)sWidth) || (sRect.y1 > (float)sHeight);
+ bool scaling = (sRect.width() != (float)dRect.width()) || (sRect.height() != (float)dRect.height());
bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
bool hasQuadLayout = Surface::hasQuadLayout(source->getInternalFormat()) || Surface::hasQuadLayout(dest->getInternalFormat());
- bool fullCopy = (sRect.x0 == 0) && (sRect.y0 == 0) && (dRect.x0 == 0) && (dRect.y0 == 0) &&
- (sRect.x1 == sWidth) && (sRect.y1 == sHeight) && (dRect.x1 == dWidth) && (dRect.y0 == dHeight);
- bool isDepth = (flags & Device::DEPTH_BUFFER) && egl::Image::isDepth(source->getInternalFormat());
- bool isStencil = (flags & Device::STENCIL_BUFFER) && (egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat()));
- bool isColor = (flags & Device::COLOR_BUFFER) == Device::COLOR_BUFFER;
+ bool fullCopy = (sRect.x0 == 0.0f) && (sRect.y0 == 0.0f) && (dRect.x0 == 0) && (dRect.y0 == 0) &&
+ (sRect.x1 == (float)sWidth) && (sRect.y1 == (float)sHeight) && (dRect.x1 == dWidth) && (dRect.y1 == dHeight);
bool alpha0xFF = false;
+ bool equalSlice = sourceSliceB == destSliceB;
+ bool smallMargin = sourcePitchB <= source->getWidth() * Surface::bytes(source->getInternalFormat()) + 16;
if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||
(source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))
@@ -607,50 +570,46 @@
alpha0xFF = true;
}
- if((isDepth || isStencil) && !scaling && equalFormats && (!hasQuadLayout || fullCopy))
+ if(fullCopy && !scaling && !isOutOfBounds && equalFormats && !alpha0xFF && equalSlice && smallMargin && !flipX && !flipY)
{
- if(source->hasDepth() && isDepth)
- {
- sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(sRect.x0, sRect.y0, 0, LOCK_READONLY, PUBLIC);
- sw::byte *destBuffer = (sw::byte*)dest->lockInternal(dRect.x0, dRect.y0, 0, LOCK_DISCARD, PUBLIC);
+ byte *sourceBuffer = isStencil ? (byte*)source->lockStencil(0, 0, 0, PUBLIC) : (byte*)source->lockInternal(0, 0, 0, LOCK_READONLY, PUBLIC);
+ byte *destBuffer = isStencil ? (byte*)dest->lockStencil(0, 0, 0, PUBLIC) : (byte*)dest->lockInternal(0, 0, 0, LOCK_DISCARD, PUBLIC);
- copyBuffer(sourceBuffer, destBuffer, dRect.width(), dRect.height(), source->getInternalPitchB(), dest->getInternalPitchB(), egl::Image::bytes(source->getInternalFormat()), flipX, flipY);
+ memcpy(destBuffer, sourceBuffer, sourceSliceB);
- source->unlockInternal();
- dest->unlockInternal();
- }
-
- if(source->hasStencil() && isStencil)
- {
- sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(sRect.x0, sRect.y0, 0, PUBLIC);
- sw::byte *destBuffer = (sw::byte*)dest->lockStencil(dRect.x0, dRect.y0, 0, PUBLIC);
-
- copyBuffer(sourceBuffer, destBuffer, source->getWidth(), source->getHeight(), source->getStencilPitchB(), dest->getStencilPitchB(), egl::Image::bytes(source->getStencilFormat()), flipX, flipY);
-
- source->unlockStencil();
- dest->unlockStencil();
- }
+ isStencil ? source->unlockStencil() : source->unlockInternal();
+ isStencil ? dest->unlockStencil() : dest->unlockInternal();
}
- else if((flags & Device::COLOR_BUFFER) && !scaling && equalFormats && (!hasQuadLayout || fullCopy))
+ else if(isDepth && !scaling && !isOutOfBounds && equalFormats && !hasQuadLayout)
{
- unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sourceRect->slice, LOCK_READONLY, PUBLIC);
- unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, destRect->slice, LOCK_READWRITE, PUBLIC);
- unsigned int sourcePitch = source->getInternalPitchB();
- unsigned int destPitch = dest->getInternalPitchB();
+ byte *sourceBuffer = (byte*)source->lockInternal((int)sRect.x0, (int)sRect.y0, 0, LOCK_READONLY, PUBLIC);
+ byte *destBuffer = (byte*)dest->lockInternal(dRect.x0, dRect.y0, 0, fullCopy ? LOCK_DISCARD : LOCK_WRITEONLY, PUBLIC);
+
+ copyBuffer(sourceBuffer, destBuffer, dRect.width(), dRect.height(), sourcePitchB, destPitchB, Surface::bytes(source->getInternalFormat()), flipX, flipY);
+
+ source->unlockInternal();
+ dest->unlockInternal();
+ }
+ else if((flags & Device::COLOR_BUFFER) && !scaling && !isOutOfBounds && equalFormats && !hasQuadLayout)
+ {
+ byte *sourceBytes = (byte*)source->lockInternal((int)sRect.x0, (int)sRect.y0, sourceRect->slice, LOCK_READONLY, PUBLIC);
+ byte *destBytes = (byte*)dest->lockInternal(dRect.x0, dRect.y0, destRect->slice, fullCopy ? LOCK_DISCARD : LOCK_WRITEONLY, PUBLIC);
unsigned int width = dRect.x1 - dRect.x0;
unsigned int height = dRect.y1 - dRect.y0;
- copyBuffer(sourceBytes, destBytes, width, height, sourcePitch, destPitch, egl::Image::bytes(source->getInternalFormat()), flipX, flipY);
+ copyBuffer(sourceBytes, destBytes, width, height, sourcePitchB, destPitchB, Surface::bytes(source->getInternalFormat()), flipX, flipY);
if(alpha0xFF)
{
- for(unsigned int y = 0; y < height; ++y, destBytes += destPitch)
+ for(unsigned int y = 0; y < height; y++)
{
- for(unsigned int x = 0; x < width; ++x)
+ for(unsigned int x = 0; x < width; x++)
{
destBytes[4 * x + 3] = 0xFF;
}
+
+ destBytes += destPitchB;
}
}
@@ -667,19 +626,17 @@
{
swap(dRect.y0, dRect.y1);
}
+
blit(source, sRect, dest, dRect, scaling && (flags & Device::USE_FILTER), isStencil);
}
- else
- {
- UNREACHABLE(false);
- }
+ else UNREACHABLE(false);
return true;
}
bool Device::stretchCube(sw::Surface *source, sw::Surface *dest)
{
- if(!source || !dest || egl::Image::isDepth(source->getInternalFormat()) || egl::Image::isStencil(source->getInternalFormat()))
+ if(!source || !dest || Surface::isDepth(source->getInternalFormat()) || Surface::isStencil(source->getInternalFormat()))
{
ERR("Invalid parameters");
return false;
@@ -707,19 +664,20 @@
{
unsigned int sourcePitch = source->getInternalPitchB();
unsigned int destPitch = dest->getInternalPitchB();
- unsigned int bytes = dWidth * egl::Image::bytes(source->getInternalFormat());
+ unsigned int bytes = dWidth * Surface::bytes(source->getInternalFormat());
- for(int z = 0; z < dDepth; ++z)
+ for(int z = 0; z < dDepth; z++)
{
unsigned char *sourceBytes = (unsigned char*)source->lockInternal(0, 0, z, LOCK_READONLY, PUBLIC);
unsigned char *destBytes = (unsigned char*)dest->lockInternal(0, 0, z, LOCK_READWRITE, PUBLIC);
- for(int y = 0; y < dHeight; ++y)
+
+ for(int y = 0; y < dHeight; y++)
{
memcpy(destBytes, sourceBytes, bytes);
if(alpha0xFF)
{
- for(int x = 0; x < dWidth; ++x)
+ for(int x = 0; x < dWidth; x++)
{
destBytes[4 * x + 3] = 0xFF;
}
@@ -728,10 +686,10 @@
sourceBytes += sourcePitch;
destBytes += destPitch;
}
- }
- source->unlockInternal();
- dest->unlockInternal();
+ source->unlockInternal();
+ dest->unlockInternal();
+ }
}
else
{
@@ -886,7 +844,7 @@
return false;
}
- if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())
+ if(rect->x1 >(int)surface->getWidth() || rect->y1 >(int)surface->getHeight())
{
return false;
}
@@ -894,6 +852,141 @@
return true;
}
+ bool Device::validRectangle(const sw::RectF *rect, sw::Surface *surface)
+ {
+ if(!rect)
+ {
+ return true;
+ }
+
+ if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ void Device::ClipDstRect(sw::RectF &srcRect, sw::Rect &dstRect, sw::Rect &clipRect, bool flipX, bool flipY)
+ {
+ if(dstRect.x0 < clipRect.x0)
+ {
+ float offset = (static_cast<float>(clipRect.x0 - dstRect.x0) / static_cast<float>(dstRect.width())) * srcRect.width();
+ if(flipX)
+ {
+ srcRect.x1 -= offset;
+ }
+ else
+ {
+ srcRect.x0 += offset;
+ }
+ dstRect.x0 = clipRect.x0;
+ }
+ if(dstRect.x1 > clipRect.x1)
+ {
+ float offset = (static_cast<float>(dstRect.x1 - clipRect.x1) / static_cast<float>(dstRect.width())) * srcRect.width();
+ if(flipX)
+ {
+ srcRect.x0 += offset;
+ }
+ else
+ {
+ srcRect.x1 -= offset;
+ }
+ dstRect.x1 = clipRect.x1;
+ }
+ if(dstRect.y0 < clipRect.y0)
+ {
+ float offset = (static_cast<float>(clipRect.y0 - dstRect.y0) / static_cast<float>(dstRect.height())) * srcRect.height();
+ if(flipY)
+ {
+ srcRect.y1 -= offset;
+ }
+ else
+ {
+ srcRect.y0 += offset;
+ }
+ dstRect.y0 = clipRect.y0;
+ }
+ if(dstRect.y1 > clipRect.y1)
+ {
+ float offset = (static_cast<float>(dstRect.y1 - clipRect.y1) / static_cast<float>(dstRect.height())) * srcRect.height();
+ if(flipY)
+ {
+ srcRect.y0 += offset;
+ }
+ else
+ {
+ srcRect.y1 -= offset;
+ }
+ dstRect.y1 = clipRect.y1;
+ }
+ }
+
+ void Device::ClipSrcRect(sw::RectF &srcRect, sw::Rect &dstRect, sw::Rect &clipRect, bool flipX, bool flipY)
+ {
+ if(srcRect.x0 < static_cast<float>(clipRect.x0))
+ {
+ float ratio = static_cast<float>(dstRect.width()) / srcRect.width();
+ float offsetf = roundf((static_cast<float>(clipRect.x0) - srcRect.x0) * ratio);
+ int offset = static_cast<int>(offsetf);
+ if(flipX)
+ {
+ dstRect.x1 -= offset;
+ }
+ else
+ {
+ dstRect.x0 += offset;
+ }
+ srcRect.x0 += offsetf / ratio;
+ }
+ if(srcRect.x1 > static_cast<float>(clipRect.x1))
+ {
+ float ratio = static_cast<float>(dstRect.width()) / srcRect.width();
+ float offsetf = roundf((srcRect.x1 - static_cast<float>(clipRect.x1)) * ratio);
+ int offset = static_cast<int>(offsetf);
+ if(flipX)
+ {
+ dstRect.x0 += offset;
+ }
+ else
+ {
+ dstRect.x1 -= offset;
+ }
+ srcRect.x1 -= offsetf / ratio;
+ }
+ if(srcRect.y0 < static_cast<float>(clipRect.y0))
+ {
+ float ratio = static_cast<float>(dstRect.height()) / srcRect.height();
+ float offsetf = roundf((static_cast<float>(clipRect.y0) - srcRect.y0) * ratio);
+ int offset = static_cast<int>(offsetf);
+ if(flipY)
+ {
+ dstRect.y1 -= offset;
+ }
+ else
+ {
+ dstRect.y0 += offset;
+ }
+ srcRect.y0 += offsetf / ratio;
+ }
+ if(srcRect.y1 > static_cast<float>(clipRect.y1))
+ {
+ float ratio = static_cast<float>(dstRect.height()) / srcRect.height();
+ float offsetf = roundf((srcRect.y1 - static_cast<float>(clipRect.y1)) * ratio);
+ int offset = static_cast<int>(offsetf);
+ if(flipY)
+ {
+ dstRect.y0 += offset;
+ }
+ else
+ {
+ dstRect.y1 -= offset;
+ }
+ srcRect.y1 -= offsetf / ratio;
+ }
+ }
+
void Device::finish()
{
synchronize();
diff --git a/src/OpenGL/libGLESv2/Device.hpp b/src/OpenGL/libGLESv2/Device.hpp
index 17c7925..1b0636b 100644
--- a/src/OpenGL/libGLESv2/Device.hpp
+++ b/src/OpenGL/libGLESv2/Device.hpp
@@ -58,25 +58,26 @@
void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
void clearDepth(float z);
void clearStencil(unsigned int stencil, unsigned int mask);
- egl::Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
- egl::Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);
void drawIndexedPrimitive(sw::DrawType type, unsigned int indexOffset, unsigned int primitiveCount);
void drawPrimitive(sw::DrawType type, unsigned int primiveCount);
void setPixelShader(const sw::PixelShader *shader);
void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
void setScissorEnable(bool enable);
- void setRenderTarget(int index, egl::Image *renderTarget);
- void setDepthBuffer(egl::Image *depthBuffer);
- void setStencilBuffer(egl::Image *stencilBuffer);
+ void setRenderTarget(int index, egl::Image *renderTarget, unsigned int layer);
+ void setDepthBuffer(egl::Image *depthBuffer, unsigned int layer);
+ void setStencilBuffer(egl::Image *stencilBuffer, unsigned int layer);
void setScissorRect(const sw::Rect &rect);
void setVertexShader(const sw::VertexShader *shader);
void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
void setViewport(const Viewport &viewport);
- bool stretchRect(sw::Surface *sourceSurface, const sw::SliceRect *sourceRect, sw::Surface *destSurface, const sw::SliceRect *destRect, unsigned char flags);
+ bool stretchRect(sw::Surface *sourceSurface, const sw::SliceRectF *sourceRect, sw::Surface *destSurface, const sw::SliceRect *destRect, unsigned char flags);
bool stretchCube(sw::Surface *sourceSurface, sw::Surface *destSurface);
void finish();
+ static void ClipDstRect(sw::RectF &srcRect, sw::Rect &dstRect, sw::Rect &clipRect, bool flipX = false, bool flipY = false);
+ static void ClipSrcRect(sw::RectF &srcRect, sw::Rect &dstRect, sw::Rect &clipRect, bool flipX = false, bool flipY = false);
+
private:
sw::Context *const context;
@@ -85,6 +86,7 @@
bool bindViewport(); // Also adjusts for scissoring
bool validRectangle(const sw::Rect *rect, sw::Surface *surface);
+ bool validRectangle(const sw::RectF *rect, sw::Surface *surface);
void copyBuffer(sw::byte *sourceBuffer, sw::byte *destBuffer, unsigned int width, unsigned int height, unsigned int sourcePitch, unsigned int destPitch, unsigned int bytes, bool flipX, bool flipY);
diff --git a/src/OpenGL/libGLESv2/Framebuffer.cpp b/src/OpenGL/libGLESv2/Framebuffer.cpp
index fa01ff3..eaa7615 100644
--- a/src/OpenGL/libGLESv2/Framebuffer.cpp
+++ b/src/OpenGL/libGLESv2/Framebuffer.cpp
@@ -22,6 +22,8 @@
#include "Texture.h"
#include "utilities.h"
+#include <algorithm>
+
namespace es2
{
@@ -32,19 +34,23 @@
Framebuffer::Framebuffer()
{
- for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
- {
- mColorbufferType[i] = GL_NONE;
- }
- mDepthbufferType = GL_NONE;
- mStencilbufferType = GL_NONE;
-
- readBuffer = GL_BACK;
- drawBuffer[0] = GL_BACK;
- for(int i = 1; i < MAX_COLOR_ATTACHMENTS; ++i)
+ readBuffer = GL_COLOR_ATTACHMENT0;
+ drawBuffer[0] = GL_COLOR_ATTACHMENT0;
+ for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++)
{
drawBuffer[i] = GL_NONE;
}
+
+ for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
+ {
+ mColorbufferType[i] = GL_NONE;
+ mColorbufferLayer[i] = 0;
+ }
+
+ mDepthbufferType = GL_NONE;
+ mDepthbufferLayer = 0;
+ mStencilbufferType = GL_NONE;
+ mStencilbufferLayer = 0;
}
Framebuffer::~Framebuffer()
@@ -57,7 +63,7 @@
mStencilbufferPointer = nullptr;
}
-Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const
+Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level) const
{
Context *context = getContext();
Renderbuffer *buffer = nullptr;
@@ -72,7 +78,7 @@
}
else if(IsTextureTarget(type))
{
- buffer = context->getTexture(handle)->getRenderbuffer(type, level, layer);
+ buffer = context->getTexture(handle)->getRenderbuffer(type, level);
}
else UNREACHABLE(type);
@@ -82,19 +88,22 @@
void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer)
{
mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE;
- mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level, layer);
+ mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level);
+ mColorbufferLayer[index] = layer;
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
{
mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
- mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level, layer);
+ mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level);
+ mDepthbufferLayer = layer;
}
void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
{
mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
- mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level, layer);
+ mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level);
+ mStencilbufferLayer = layer;
}
void Framebuffer::setReadBuffer(GLenum buf)
@@ -169,11 +178,14 @@
// caller must Release() the returned surface
egl::Image *Framebuffer::getRenderTarget(GLuint index)
{
- Renderbuffer *colorbuffer = mColorbufferPointer[index];
-
- if(colorbuffer)
+ if(index < MAX_COLOR_ATTACHMENTS)
{
- return colorbuffer->getRenderTarget();
+ Renderbuffer *colorbuffer = mColorbufferPointer[index];
+
+ if(colorbuffer)
+ {
+ return colorbuffer->getRenderTarget();
+ }
}
return nullptr;
@@ -181,8 +193,7 @@
egl::Image *Framebuffer::getReadRenderTarget()
{
- Context *context = getContext();
- return getRenderTarget(context->getReadFramebufferColorIndex());
+ return getRenderTarget(getReadBufferIndex());
}
// Increments refcount on surface.
@@ -220,8 +231,7 @@
Renderbuffer *Framebuffer::getReadColorbuffer() const
{
- Context *context = getContext();
- return getColorbuffer(context->getReadFramebufferColorIndex());
+ return getColorbuffer(getReadBufferIndex());
}
Renderbuffer *Framebuffer::getDepthbuffer() const
@@ -234,6 +244,16 @@
return mStencilbufferPointer;
}
+GLenum Framebuffer::getReadBufferType()
+{
+ if(readBuffer == GL_NONE)
+ {
+ return GL_NONE;
+ }
+
+ return mColorbufferType[getReadBufferIndex()];
+}
+
GLenum Framebuffer::getColorbufferType(GLuint index)
{
return mColorbufferType[index];
@@ -266,18 +286,17 @@
GLint Framebuffer::getColorbufferLayer(GLuint index)
{
- Renderbuffer *colorbuffer = mColorbufferPointer[index];
- return colorbuffer ? colorbuffer->getLayer() : 0;
+ return mColorbufferLayer[index];
}
GLint Framebuffer::getDepthbufferLayer()
{
- return mDepthbufferPointer ? mDepthbufferPointer->getLayer() : 0;
+ return mDepthbufferLayer;
}
GLint Framebuffer::getStencilbufferLayer()
{
- return mStencilbufferPointer ? mStencilbufferPointer->getLayer() : 0;
+ return mStencilbufferLayer;
}
bool Framebuffer::hasStencil()
@@ -310,6 +329,8 @@
height = -1;
samples = -1;
+ GLint version = egl::getClientVersion();
+
for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
{
if(mColorbufferType[i] != GL_NONE)
@@ -321,14 +342,14 @@
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= colorbuffer->getLayer()))
+ if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0 || (colorbuffer->getDepth() <= mColorbufferLayer[i]))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(IsRenderbuffer(mColorbufferType[i]))
{
- if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion(), false))
+ if(!IsColorRenderable(colorbuffer->getFormat(), version))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -337,7 +358,7 @@
{
GLenum format = colorbuffer->getFormat();
- if(!IsColorRenderable(format, egl::getClientVersion(), true))
+ if(!IsColorRenderable(format, version))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -353,16 +374,26 @@
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- width = colorbuffer->getWidth();
- height = colorbuffer->getHeight();
-
- if(samples == -1)
+ if(width == -1 || height == -1)
{
+ width = colorbuffer->getWidth();
+ height = colorbuffer->getHeight();
samples = colorbuffer->getSamples();
}
- else if(samples != colorbuffer->getSamples())
+ else
{
- return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ if(version < 3 && (width != colorbuffer->getWidth() || height != colorbuffer->getHeight()))
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+
+ if(samples != colorbuffer->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ }
+
+ width = std::min(width, colorbuffer->getWidth());
+ height = std::min(height, colorbuffer->getHeight());
}
}
}
@@ -379,14 +410,14 @@
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
+ if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0 || (depthbuffer->getDepth() <= mDepthbufferLayer))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(IsRenderbuffer(mDepthbufferType))
{
- if(!es2::IsDepthRenderable(depthbuffer->getFormat(), egl::getClientVersion()))
+ if(!es2::IsDepthRenderable(depthbuffer->getFormat(), version))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -410,13 +441,20 @@
height = depthbuffer->getHeight();
samples = depthbuffer->getSamples();
}
- else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
+ else
{
- return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
- }
- else if(samples != depthbuffer->getSamples())
- {
- return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ if(version < 3 && (width != depthbuffer->getWidth() || height != depthbuffer->getHeight()))
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+
+ if(samples != depthbuffer->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ }
+
+ width = std::min(width, depthbuffer->getWidth());
+ height = std::min(height, depthbuffer->getHeight());
}
}
@@ -429,14 +467,14 @@
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
+ if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0 || (stencilbuffer->getDepth() <= mStencilbufferLayer))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(IsRenderbuffer(mStencilbufferType))
{
- if(!es2::IsStencilRenderable(stencilbuffer->getFormat(), egl::getClientVersion()))
+ if(!es2::IsStencilRenderable(stencilbuffer->getFormat(), version))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -462,17 +500,24 @@
height = stencilbuffer->getHeight();
samples = stencilbuffer->getSamples();
}
- else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
+ else
{
- return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
- }
- else if(samples != stencilbuffer->getSamples())
- {
- return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ if(version < 3 && (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight()))
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+
+ if(samples != stencilbuffer->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
+ }
+
+ width = std::min(width, stencilbuffer->getWidth());
+ height = std::min(height, stencilbuffer->getHeight());
}
}
- if((egl::getClientVersion() >= 3) && depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
+ if((version >= 3) && depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
{
// In the GLES 3.0 spec, section 4.4.4, Framebuffer Completeness:
// "The framebuffer object target is said to be framebuffer complete if all the following conditions are true:
@@ -497,57 +542,55 @@
if(colorbuffer)
{
- switch(colorbuffer->getInternalFormat())
+ switch(colorbuffer->getFormat())
{
- case sw::FORMAT_A8B8G8R8I: return GL_RGBA_INTEGER;
- case sw::FORMAT_A8B8G8R8UI: return GL_RGBA_INTEGER;
- case sw::FORMAT_A16B16G16R16I: return GL_RGBA_INTEGER;
- case sw::FORMAT_A16B16G16R16UI: return GL_RGBA_INTEGER;
- case sw::FORMAT_A32B32G32R32I: return GL_RGBA_INTEGER;
- case sw::FORMAT_A32B32G32R32UI: return GL_RGBA_INTEGER;
- case sw::FORMAT_A2B10G10R10: return GL_RGB10_A2;
- case sw::FORMAT_A8B8G8R8I_SNORM: return GL_RGBA;
- case sw::FORMAT_A8B8G8R8: return GL_RGBA;
- case sw::FORMAT_SRGB8_A8: return GL_RGBA;
- case sw::FORMAT_A8R8G8B8: return GL_BGRA_EXT;
- case sw::FORMAT_A1R5G5B5: return GL_BGRA_EXT;
- case sw::FORMAT_X8B8G8R8I: return GL_RGBA_INTEGER;
- case sw::FORMAT_X8B8G8R8UI: return GL_RGBA_INTEGER;
- case sw::FORMAT_X16B16G16R16I: return GL_RGBA_INTEGER;
- case sw::FORMAT_X16B16G16R16UI: return GL_RGBA_INTEGER;
- case sw::FORMAT_X32B32G32R32I: return GL_RGBA_INTEGER;
- case sw::FORMAT_X32B32G32R32UI: return GL_RGBA_INTEGER;
- case sw::FORMAT_X8B8G8R8I_SNORM: return GL_RGBA;
- case sw::FORMAT_SRGB8_X8: return GL_RGBA;
- case sw::FORMAT_X8B8G8R8: return GL_RGBA;
- case sw::FORMAT_X8R8G8B8: return GL_BGRA_EXT;
- case sw::FORMAT_R5G6B5: return GL_RGB;
- case sw::FORMAT_G8R8I: return GL_RG_INTEGER;
- case sw::FORMAT_G8R8UI: return GL_RG_INTEGER;
- case sw::FORMAT_G16R16I: return GL_RG_INTEGER;
- case sw::FORMAT_G16R16UI: return GL_RG_INTEGER;
- case sw::FORMAT_G32R32I: return GL_RG_INTEGER;
- case sw::FORMAT_G32R32UI: return GL_RG_INTEGER;
- case sw::FORMAT_R8I: return GL_RED_INTEGER;
- case sw::FORMAT_R8UI: return GL_RED_INTEGER;
- case sw::FORMAT_R16I: return GL_RED_INTEGER;
- case sw::FORMAT_R16UI: return GL_RED_INTEGER;
- case sw::FORMAT_R32I: return GL_RED_INTEGER;
- case sw::FORMAT_R32UI: return GL_RED_INTEGER;
- case sw::FORMAT_R8: return GL_RED;
- case sw::FORMAT_R8I_SNORM: return GL_RED;
- case sw::FORMAT_R16F: return GL_RED;
- case sw::FORMAT_R32F: return GL_RED;
- case sw::FORMAT_G8R8: return GL_RG;
- case sw::FORMAT_G8R8I_SNORM: return GL_RG;
- case sw::FORMAT_G16R16F: return GL_RG;
- case sw::FORMAT_G32R32F: return GL_RG;
- case sw::FORMAT_B16G16R16F: return GL_RGB;
- case sw::FORMAT_X32B32G32R32F: return GL_RGBA;
- case sw::FORMAT_A16B16G16R16F: return GL_RGBA;
- case sw::FORMAT_A32B32G32R32F: return GL_RGBA;
+ case GL_BGRA8_EXT: return GL_BGRA_EXT;
+ case GL_RGBA4: return GL_RGBA;
+ case GL_RGB5_A1: return GL_RGBA;
+ case GL_RGBA8: return GL_RGBA;
+ case GL_RGB565: return GL_RGBA;
+ case GL_RGB8: return GL_RGB;
+ case GL_R8: return GL_RED;
+ case GL_RG8: return GL_RG;
+ case GL_R8I: return GL_RED_INTEGER;
+ case GL_RG8I: return GL_RG_INTEGER;
+ case GL_RGB8I: return GL_RGB_INTEGER;
+ case GL_RGBA8I: return GL_RGBA_INTEGER;
+ case GL_R8UI: return GL_RED_INTEGER;
+ case GL_RG8UI: return GL_RG_INTEGER;
+ case GL_RGB8UI: return GL_RGB_INTEGER;
+ case GL_RGBA8UI: return GL_RGBA_INTEGER;
+ case GL_R16I: return GL_RED_INTEGER;
+ case GL_RG16I: return GL_RG_INTEGER;
+ case GL_RGB16I: return GL_RGB_INTEGER;
+ case GL_RGBA16I: return GL_RGBA_INTEGER;
+ case GL_R16UI: return GL_RED_INTEGER;
+ case GL_RG16UI: return GL_RG_INTEGER;
+ case GL_RGB16UI: return GL_RGB_INTEGER;
+ case GL_RGB10_A2UI: return GL_RGBA_INTEGER;
+ case GL_RGBA16UI: return GL_RGBA_INTEGER;
+ case GL_R32I: return GL_RED_INTEGER;
+ case GL_RG32I: return GL_RG_INTEGER;
+ case GL_RGB32I: return GL_RGB_INTEGER;
+ case GL_RGBA32I: return GL_RGBA_INTEGER;
+ case GL_R32UI: return GL_RED_INTEGER;
+ case GL_RG32UI: return GL_RG_INTEGER;
+ case GL_RGB32UI: return GL_RGB_INTEGER;
+ case GL_RGBA32UI: return GL_RGBA_INTEGER;
+ case GL_R16F: return GL_RED;
+ case GL_RG16F: return GL_RG;
+ case GL_R11F_G11F_B10F: return GL_RGB;
+ case GL_RGB16F: return GL_RGB;
+ case GL_RGBA16F: return GL_RGBA;
+ case GL_R32F: return GL_RED;
+ case GL_RG32F: return GL_RG;
+ case GL_RGB32F: return GL_RGB;
+ case GL_RGBA32F: return GL_RGBA;
+ case GL_RGB10_A2: return GL_RGBA;
+ case GL_SRGB8: return GL_RGB;
+ case GL_SRGB8_ALPHA8: return GL_RGBA;
default:
- UNREACHABLE(colorbuffer->getInternalFormat());
+ UNREACHABLE(colorbuffer->getFormat());
}
}
@@ -560,58 +603,55 @@
if(colorbuffer)
{
- switch(colorbuffer->getInternalFormat())
+ switch(colorbuffer->getFormat())
{
- case sw::FORMAT_R16F: return GL_FLOAT;
- case sw::FORMAT_G16R16F: return GL_FLOAT;
- case sw::FORMAT_B16G16R16F: return GL_FLOAT;
- case sw::FORMAT_A16B16G16R16F: return GL_FLOAT;
- case sw::FORMAT_R32F: return GL_FLOAT;
- case sw::FORMAT_G32R32F: return GL_FLOAT;
- case sw::FORMAT_B32G32R32F: return GL_FLOAT;
- case sw::FORMAT_X32B32G32R32F: return GL_FLOAT;
- case sw::FORMAT_A32B32G32R32F: return GL_FLOAT;
- case sw::FORMAT_R8I_SNORM: return GL_BYTE;
- case sw::FORMAT_G8R8I_SNORM: return GL_BYTE;
- case sw::FORMAT_X8B8G8R8I_SNORM: return GL_BYTE;
- case sw::FORMAT_A8B8G8R8I_SNORM: return GL_BYTE;
- case sw::FORMAT_R8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_G8R8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_SRGB8_X8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_SRGB8_A8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_A8R8G8B8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_A8B8G8R8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_X8R8G8B8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_X8B8G8R8: return GL_UNSIGNED_BYTE;
- case sw::FORMAT_R8I: return GL_INT;
- case sw::FORMAT_G8R8I: return GL_INT;
- case sw::FORMAT_X8B8G8R8I: return GL_INT;
- case sw::FORMAT_A8B8G8R8I: return GL_INT;
- case sw::FORMAT_R16I: return GL_INT;
- case sw::FORMAT_G16R16I: return GL_INT;
- case sw::FORMAT_X16B16G16R16I: return GL_INT;
- case sw::FORMAT_A16B16G16R16I: return GL_INT;
- case sw::FORMAT_R32I: return GL_INT;
- case sw::FORMAT_G32R32I: return GL_INT;
- case sw::FORMAT_X32B32G32R32I: return GL_INT;
- case sw::FORMAT_A32B32G32R32I: return GL_INT;
- case sw::FORMAT_R8UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_G8R8UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_X8B8G8R8UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_A8B8G8R8UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_R16UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_G16R16UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_X16B16G16R16UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_A16B16G16R16UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_R32UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_G32R32UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_X32B32G32R32UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_A32B32G32R32UI: return GL_UNSIGNED_INT;
- case sw::FORMAT_A2B10G10R10: return GL_UNSIGNED_INT_10_10_10_2_OES;
- case sw::FORMAT_A1R5G5B5: return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT;
- case sw::FORMAT_R5G6B5: return GL_UNSIGNED_SHORT_5_6_5;
+ case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE;
+ case GL_RGBA4: return GL_UNSIGNED_SHORT_4_4_4_4;
+ case GL_RGB5_A1: return GL_UNSIGNED_SHORT_5_5_5_1;
+ case GL_RGBA8: return GL_UNSIGNED_BYTE;
+ case GL_RGB565: return GL_UNSIGNED_SHORT_5_6_5;
+ case GL_RGB8: return GL_UNSIGNED_BYTE;
+ case GL_R8: return GL_UNSIGNED_BYTE;
+ case GL_RG8: return GL_UNSIGNED_BYTE;
+ case GL_R8I: return GL_INT;
+ case GL_RG8I: return GL_INT;
+ case GL_RGB8I: return GL_INT;
+ case GL_RGBA8I: return GL_INT;
+ case GL_R8UI: return GL_UNSIGNED_BYTE;
+ case GL_RG8UI: return GL_UNSIGNED_BYTE;
+ case GL_RGB8UI: return GL_UNSIGNED_BYTE;
+ case GL_RGBA8UI: return GL_UNSIGNED_BYTE;
+ case GL_R16I: return GL_INT;
+ case GL_RG16I: return GL_INT;
+ case GL_RGB16I: return GL_INT;
+ case GL_RGBA16I: return GL_INT;
+ case GL_R16UI: return GL_UNSIGNED_INT;
+ case GL_RG16UI: return GL_UNSIGNED_INT;
+ case GL_RGB16UI: return GL_UNSIGNED_INT;
+ case GL_RGB10_A2UI: return GL_UNSIGNED_INT_2_10_10_10_REV;
+ case GL_RGBA16UI: return GL_UNSIGNED_INT;
+ case GL_R32I: return GL_INT;
+ case GL_RG32I: return GL_INT;
+ case GL_RGB32I: return GL_INT;
+ case GL_RGBA32I: return GL_INT;
+ case GL_R32UI: return GL_UNSIGNED_INT;
+ case GL_RG32UI: return GL_UNSIGNED_INT;
+ case GL_RGB32UI: return GL_UNSIGNED_INT;
+ case GL_RGBA32UI: return GL_UNSIGNED_INT;
+ case GL_R16F: return GL_FLOAT;
+ case GL_RG16F: return GL_FLOAT;
+ case GL_R11F_G11F_B10F: return GL_FLOAT;
+ case GL_RGB16F: return GL_FLOAT;
+ case GL_RGBA16F: return GL_FLOAT;
+ case GL_R32F: return GL_FLOAT;
+ case GL_RG32F: return GL_FLOAT;
+ case GL_RGB32F: return GL_FLOAT;
+ case GL_RGBA32F: return GL_FLOAT;
+ case GL_RGB10_A2: return GL_UNSIGNED_INT_2_10_10_10_REV;
+ case GL_SRGB8: return GL_UNSIGNED_BYTE;
+ case GL_SRGB8_ALPHA8: return GL_UNSIGNED_BYTE;
default:
- UNREACHABLE(colorbuffer->getInternalFormat());
+ UNREACHABLE(colorbuffer->getFormat());
}
}
@@ -638,18 +678,16 @@
if(depthbuffer)
{
- switch(depthbuffer->getInternalFormat())
+ switch(depthbuffer->getFormat())
{
- case sw::FORMAT_D16: return GL_UNSIGNED_SHORT;
- case sw::FORMAT_D24S8: return GL_UNSIGNED_INT_24_8_OES;
- case sw::FORMAT_D32: return GL_UNSIGNED_INT;
- case sw::FORMAT_D32F:
- case sw::FORMAT_D32F_COMPLEMENTARY:
- case sw::FORMAT_D32F_LOCKABLE:
- case sw::FORMAT_D32FS8_TEXTURE:
- case sw::FORMAT_D32FS8_SHADOW: return GL_FLOAT;
+ case GL_DEPTH_COMPONENT16: return GL_UNSIGNED_SHORT;
+ case GL_DEPTH_COMPONENT24: return GL_UNSIGNED_INT;
+ case GL_DEPTH_COMPONENT32_OES: return GL_UNSIGNED_INT;
+ case GL_DEPTH_COMPONENT32F: return GL_FLOAT;
+ case GL_DEPTH24_STENCIL8: return GL_UNSIGNED_INT_24_8_OES;
+ case GL_DEPTH32F_STENCIL8: return GL_FLOAT;
default:
- UNREACHABLE(depthbuffer->getInternalFormat());
+ UNREACHABLE(depthbuffer->getFormat());
}
}
@@ -657,12 +695,33 @@
return GL_NONE;
}
+GLuint Framebuffer::getReadBufferIndex() const
+{
+ switch(readBuffer)
+ {
+ case GL_BACK:
+ return 0;
+ case GL_NONE:
+ return GL_INVALID_INDEX;
+ default:
+ return readBuffer - GL_COLOR_ATTACHMENT0;
+ }
+}
+
+DefaultFramebuffer::DefaultFramebuffer()
+{
+ readBuffer = GL_BACK;
+ drawBuffer[0] = GL_BACK;
+}
+
DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
{
GLenum defaultRenderbufferType = egl::getClientVersion() < 3 ? GL_RENDERBUFFER : GL_FRAMEBUFFER_DEFAULT;
mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer);
mColorbufferType[0] = defaultRenderbufferType;
+ readBuffer = GL_BACK;
+ drawBuffer[0] = GL_BACK;
for(int i = 1; i < MAX_COLOR_ATTACHMENTS; i++)
{
mColorbufferPointer[i] = nullptr;
diff --git a/src/OpenGL/libGLESv2/Framebuffer.h b/src/OpenGL/libGLESv2/Framebuffer.h
index 1405031..e1a3611 100644
--- a/src/OpenGL/libGLESv2/Framebuffer.h
+++ b/src/OpenGL/libGLESv2/Framebuffer.h
@@ -61,6 +61,7 @@
Renderbuffer *getDepthbuffer() const;
Renderbuffer *getStencilbuffer() const;
+ GLenum getReadBufferType();
GLenum getColorbufferType(GLuint index);
GLenum getDepthbufferType();
GLenum getStencilbufferType();
@@ -88,24 +89,31 @@
static bool IsRenderbuffer(GLenum type);
protected:
- GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS];
- gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS];
+ GLuint getReadBufferIndex() const;
+
GLenum readBuffer;
GLenum drawBuffer[MAX_COLOR_ATTACHMENTS];
+ GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS];
+ gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS];
+ GLint mColorbufferLayer[MAX_COLOR_ATTACHMENTS];
+
GLenum mDepthbufferType;
gl::BindingPointer<Renderbuffer> mDepthbufferPointer;
+ GLint mDepthbufferLayer;
GLenum mStencilbufferType;
gl::BindingPointer<Renderbuffer> mStencilbufferPointer;
+ GLint mStencilbufferLayer;
private:
- Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const;
+ Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle, GLint level) const;
};
class DefaultFramebuffer : public Framebuffer
{
public:
+ DefaultFramebuffer();
DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
bool isDefaultFramebuffer() const override { return true; }
diff --git a/src/OpenGL/libGLESv2/IndexDataManager.cpp b/src/OpenGL/libGLESv2/IndexDataManager.cpp
index 81d1c6a..55c15b2 100644
--- a/src/OpenGL/libGLESv2/IndexDataManager.cpp
+++ b/src/OpenGL/libGLESv2/IndexDataManager.cpp
@@ -63,37 +63,214 @@
else UNREACHABLE(type);
}
-template<class IndexType>
-void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+inline GLsizei getNumIndices(const std::vector<GLsizei>& restartIndices, size_t i, GLsizei count)
{
- *minIndex = indices[0];
- *maxIndex = indices[0];
+ return restartIndices.empty() ? count :
+ ((i == 0) ? restartIndices[0] : ((i == restartIndices.size()) ? (count - restartIndices[i - 1] - 1) : (restartIndices[i] - restartIndices[i - 1] - 1)));
+}
+
+void copyIndices(GLenum mode, GLenum type, const std::vector<GLsizei>& restartIndices, const void *input, GLsizei count, void* output)
+{
+ size_t bytesPerIndex = 0;
+ const unsigned char* inPtr = static_cast<const unsigned char*>(input);
+ unsigned char* outPtr = static_cast<unsigned char*>(output);
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ bytesPerIndex = sizeof(GLubyte);
+ break;
+ case GL_UNSIGNED_INT:
+ bytesPerIndex = sizeof(GLuint);
+ break;
+ case GL_UNSIGNED_SHORT:
+ bytesPerIndex = sizeof(GLushort);
+ break;
+ default:
+ UNREACHABLE(type);
+ }
+
+ size_t numRestarts = restartIndices.size();
+ switch(mode)
+ {
+ case GL_TRIANGLES:
+ case GL_LINES:
+ case GL_POINTS:
+ {
+ GLsizei verticesPerPrimitive = (mode == GL_TRIANGLES) ? 3 : ((mode == GL_LINES) ? 2 : 1);
+ for(size_t i = 0; i <= numRestarts; ++i)
+ {
+ GLsizei numIndices = getNumIndices(restartIndices, i, count);
+ size_t numBytes = (numIndices / verticesPerPrimitive) * verticesPerPrimitive * bytesPerIndex;
+ if(numBytes > 0)
+ {
+ memcpy(outPtr, inPtr, numBytes);
+ outPtr += numBytes;
+ }
+ inPtr += (numIndices + 1) * bytesPerIndex;
+ }
+ }
+ break;
+ case GL_TRIANGLE_FAN:
+ for(size_t i = 0; i <= numRestarts; ++i)
+ {
+ GLsizei numIndices = getNumIndices(restartIndices, i, count);
+ GLsizei numTriangles = (numIndices - 2);
+ for(GLsizei tri = 0; tri < numTriangles; ++tri)
+ {
+ memcpy(outPtr, inPtr, bytesPerIndex);
+ outPtr += bytesPerIndex;
+ memcpy(outPtr, inPtr + ((tri + 1) * bytesPerIndex), bytesPerIndex + bytesPerIndex);
+ outPtr += bytesPerIndex + bytesPerIndex;
+ }
+ inPtr += (numIndices + 1) * bytesPerIndex;
+ }
+ break;
+ case GL_TRIANGLE_STRIP:
+ for(size_t i = 0; i <= numRestarts; ++i)
+ {
+ GLsizei numIndices = getNumIndices(restartIndices, i, count);
+ GLsizei numTriangles = (numIndices - 2);
+ for(GLsizei tri = 0; tri < numTriangles; ++tri)
+ {
+ if(tri & 1) // Reverse odd triangles
+ {
+ memcpy(outPtr, inPtr + ((tri + 1) * bytesPerIndex), bytesPerIndex);
+ outPtr += bytesPerIndex;
+ memcpy(outPtr, inPtr + ((tri + 0) * bytesPerIndex), bytesPerIndex);
+ outPtr += bytesPerIndex;
+ memcpy(outPtr, inPtr + ((tri + 2) * bytesPerIndex), bytesPerIndex);
+ outPtr += bytesPerIndex;
+ }
+ else
+ {
+ size_t numBytes = 3 * bytesPerIndex;
+ memcpy(outPtr, inPtr + (tri * bytesPerIndex), numBytes);
+ outPtr += numBytes;
+ }
+ }
+ inPtr += (numIndices + 1) * bytesPerIndex;
+ }
+ break;
+ case GL_LINE_LOOP:
+ for(size_t i = 0; i <= numRestarts; ++i)
+ {
+ GLsizei numIndices = getNumIndices(restartIndices, i, count);
+ if(numIndices >= 2)
+ {
+ GLsizei numLines = numIndices;
+ memcpy(outPtr, inPtr + (numIndices - 1) * bytesPerIndex, bytesPerIndex); // Last vertex
+ outPtr += bytesPerIndex;
+ memcpy(outPtr, inPtr, bytesPerIndex); // First vertex
+ outPtr += bytesPerIndex;
+ size_t bytesPerLine = 2 * bytesPerIndex;
+ for(GLsizei tri = 0; tri < (numLines - 1); ++tri)
+ {
+ memcpy(outPtr, inPtr + tri * bytesPerIndex, bytesPerLine);
+ outPtr += bytesPerLine;
+ }
+ }
+ inPtr += (numIndices + 1) * bytesPerIndex;
+ }
+ break;
+ case GL_LINE_STRIP:
+ for(size_t i = 0; i <= numRestarts; ++i)
+ {
+ GLsizei numIndices = getNumIndices(restartIndices, i, count);
+ GLsizei numLines = numIndices - 1;
+ size_t bytesPerLine = 2 * bytesPerIndex;
+ for(GLsizei tri = 0; tri < numLines; ++tri)
+ {
+ memcpy(outPtr, inPtr + tri * bytesPerIndex, bytesPerLine);
+ outPtr += bytesPerLine;
+ }
+ inPtr += (numIndices + 1) * bytesPerIndex;
+ }
+ break;
+ default:
+ UNREACHABLE(mode);
+ break;
+ }
+}
+
+template<class IndexType>
+void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex, std::vector<GLsizei>* restartIndices)
+{
+ *maxIndex = 0;
+ *minIndex = MAX_ELEMENTS_INDICES;
for(GLsizei i = 0; i < count; i++)
{
+ if(restartIndices && indices[i] == IndexType(-1))
+ {
+ restartIndices->push_back(i);
+ continue;
+ }
if(*minIndex > indices[i]) *minIndex = indices[i];
if(*maxIndex < indices[i]) *maxIndex = indices[i];
}
}
-void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex, std::vector<GLsizei>* restartIndices)
{
if(type == GL_UNSIGNED_BYTE)
{
- computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
+ computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex, restartIndices);
}
else if(type == GL_UNSIGNED_INT)
{
- computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
+ computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex, restartIndices);
}
else if(type == GL_UNSIGNED_SHORT)
{
- computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
+ computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex, restartIndices);
}
else UNREACHABLE(type);
}
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
+int recomputePrimitiveCount(GLenum mode, GLsizei count, const std::vector<GLsizei>& restartIndices, unsigned int* primitiveCount)
+{
+ size_t numRestarts = restartIndices.size();
+ *primitiveCount = 0;
+
+ unsigned int countOffset = 0;
+ unsigned int vertexPerPrimitive = 0;
+
+ switch(mode)
+ {
+ case GL_TRIANGLES: // 3 vertex per primitive
+ ++vertexPerPrimitive;
+ case GL_LINES: // 2 vertex per primitive
+ vertexPerPrimitive += 2;
+ for(size_t i = 0; i <= numRestarts; ++i)
+ {
+ unsigned int nbIndices = getNumIndices(restartIndices, i, count);
+ *primitiveCount += nbIndices / vertexPerPrimitive;
+ }
+ return vertexPerPrimitive;
+ case GL_TRIANGLE_FAN:
+ case GL_TRIANGLE_STRIP: // (N - 2) polygons, 3 vertex per primitive
+ ++vertexPerPrimitive;
+ --countOffset;
+ case GL_LINE_STRIP: // (N - 1) polygons, 2 vertex per primitive
+ --countOffset;
+ case GL_LINE_LOOP: // N polygons, 2 vertex per primitive
+ vertexPerPrimitive += 2;
+ for(size_t i = 0; i <= numRestarts; ++i)
+ {
+ unsigned int nbIndices = getNumIndices(restartIndices, i, count);
+ *primitiveCount += (nbIndices >= vertexPerPrimitive) ? (nbIndices + countOffset) : 0;
+ }
+ return vertexPerPrimitive;
+ case GL_POINTS:
+ *primitiveCount = static_cast<unsigned int>(count - restartIndices.size());
+ return 1;
+ default:
+ UNREACHABLE(mode);
+ return -1;
+ }
+}
+
+GLenum IndexDataManager::prepareIndexData(GLenum mode, GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated, bool primitiveRestart)
{
if(!mStreamingBuffer)
{
@@ -112,14 +289,44 @@
indices = static_cast<const GLubyte*>(buffer->data()) + offset;
}
+ std::vector<GLsizei>* restartIndices = primitiveRestart ? new std::vector<GLsizei>() : nullptr;
+ computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex, restartIndices);
+
StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;
sw::Resource *staticBuffer = buffer ? buffer->getResource() : NULL;
- if(staticBuffer)
+ if(restartIndices)
{
- computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+ int vertexPerPrimitive = recomputePrimitiveCount(mode, count, *restartIndices, &translated->primitiveCount);
+ if(vertexPerPrimitive == -1)
+ {
+ delete restartIndices;
+ return GL_INVALID_ENUM;
+ }
+ size_t streamOffset = 0;
+ int convertCount = translated->primitiveCount * vertexPerPrimitive;
+
+ streamingBuffer->reserveSpace(convertCount * typeSize(type), type);
+ void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);
+
+ if(output == NULL)
+ {
+ delete restartIndices;
+ ERR("Failed to map index buffer.");
+ return GL_OUT_OF_MEMORY;
+ }
+
+ copyIndices(mode, type, *restartIndices, staticBuffer ? buffer->data() : indices, count, output);
+ streamingBuffer->unmap();
+
+ translated->indexBuffer = streamingBuffer->getResource();
+ translated->indexOffset = static_cast<unsigned int>(streamOffset);
+ delete restartIndices;
+ }
+ else if(staticBuffer)
+ {
translated->indexBuffer = staticBuffer;
translated->indexOffset = static_cast<unsigned int>(offset);
}
@@ -137,11 +344,9 @@
return GL_OUT_OF_MEMORY;
}
- copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
+ copyIndices(type, indices, convertCount, output);
streamingBuffer->unmap();
- computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-
translated->indexBuffer = streamingBuffer->getResource();
translated->indexOffset = static_cast<unsigned int>(streamOffset);
}
diff --git a/src/OpenGL/libGLESv2/IndexDataManager.h b/src/OpenGL/libGLESv2/IndexDataManager.h
index 0a5e398..1834fbc 100644
--- a/src/OpenGL/libGLESv2/IndexDataManager.h
+++ b/src/OpenGL/libGLESv2/IndexDataManager.h
@@ -27,9 +27,12 @@
struct TranslatedIndexData
{
+ TranslatedIndexData(unsigned int primitiveCount) : primitiveCount(primitiveCount) {}
+
unsigned int minIndex;
unsigned int maxIndex;
unsigned int indexOffset;
+ unsigned int primitiveCount;
sw::Resource *indexBuffer;
};
@@ -58,7 +61,7 @@
IndexDataManager();
virtual ~IndexDataManager();
- GLenum prepareIndexData(GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
+ GLenum prepareIndexData(GLenum mode, GLenum type, GLuint start, GLuint end, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated, bool primitiveRestart);
static std::size_t typeSize(GLenum type);
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index 7eda6f5..d2cff33 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -61,11 +61,11 @@
}
}
- Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
- const BlockInfo &blockInfo)
- : type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo)
+ Uniform::Uniform(const glsl::Uniform &uniform, const BlockInfo &blockInfo)
+ : type(uniform.type), precision(uniform.precision), name(uniform.name),
+ arraySize(uniform.arraySize), blockInfo(blockInfo), fields(uniform.fields)
{
- if(blockInfo.index == -1)
+ if((blockInfo.index == -1) && uniform.fields.empty())
{
size_t bytes = UniformTypeSize(type) * size();
data = new unsigned char[bytes];
@@ -261,13 +261,24 @@
std::string baseName(name);
unsigned int subscript = GL_INVALID_INDEX;
baseName = ParseUniformName(baseName, &subscript);
- for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input)
+ for(auto const &varying : fragmentShader->varyings)
{
- if(input->name == baseName)
+ if(varying.qualifier == EvqFragmentOut)
{
- int rowCount = VariableRowCount(input->type);
- int colCount = VariableColumnCount(input->type);
- return (subscript == GL_INVALID_INDEX) ? input->reg : input->reg + (rowCount > 1 ? colCount * subscript : subscript);
+ if(varying.name == baseName)
+ {
+ ASSERT(varying.registerIndex >= 0);
+
+ if(subscript == GL_INVALID_INDEX) // No subscript
+ {
+ return varying.registerIndex;
+ }
+
+ int rowCount = VariableRowCount(varying.type);
+ int colCount = VariableColumnCount(varying.type);
+
+ return varying.registerIndex + (rowCount > 1 ? colCount * subscript : subscript);
+ }
}
}
}
@@ -277,26 +288,19 @@
void Program::bindAttributeLocation(GLuint index, const char *name)
{
- if(index < MAX_VERTEX_ATTRIBS)
- {
- for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- attributeBinding[i].erase(name);
- }
-
- attributeBinding[index].insert(name);
- }
+ attributeBinding[name] = index;
}
GLint Program::getAttributeLocation(const char *name)
{
if(name)
{
- for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+ std::string strName(name);
+ for(auto const &it : linkedAttribute)
{
- if(linkedAttribute[index].name == std::string(name))
+ if(it.name == strName)
{
- return index;
+ return getAttributeBinding(it);
}
}
}
@@ -364,6 +368,26 @@
return TEXTURE_2D;
}
+ bool Program::isUniformDefined(const std::string &name) const
+ {
+ unsigned int subscript = GL_INVALID_INDEX;
+ std::string baseName = es2::ParseUniformName(name, &subscript);
+
+ size_t numUniforms = uniformIndex.size();
+ for(size_t location = 0; location < numUniforms; location++)
+ {
+ const unsigned int index = uniformIndex[location].index;
+ if((uniformIndex[location].name == baseName) && ((index == GL_INVALID_INDEX) ||
+ ((uniforms[index]->isArray() && uniformIndex[location].element == subscript) ||
+ (subscript == GL_INVALID_INDEX))))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
GLint Program::getUniformLocation(const std::string &name) const
{
unsigned int subscript = GL_INVALID_INDEX;
@@ -372,11 +396,9 @@
size_t numUniforms = uniformIndex.size();
for(size_t location = 0; location < numUniforms; location++)
{
- const int index = uniformIndex[location].index;
- const bool isArray = uniforms[index]->isArray();
-
- if(uniformIndex[location].name == baseName &&
- ((isArray && uniformIndex[location].element == subscript) ||
+ const unsigned int index = uniformIndex[location].index;
+ if((index != GL_INVALID_INDEX) && (uniformIndex[location].name == baseName) &&
+ ((uniforms[index]->isArray() && uniformIndex[location].element == subscript) ||
(subscript == GL_INVALID_INDEX)))
{
return (GLint)location;
@@ -471,11 +493,20 @@
void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
+ if(uniformBlockIndex >= getActiveUniformBlockCount())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
}
GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
{
+ if(uniformBlockIndex >= getActiveUniformBlockCount())
+ {
+ return error(GL_INVALID_VALUE, GL_INVALID_INDEX);
+ }
return uniformBlockBindings[uniformBlockIndex];
}
@@ -494,7 +525,7 @@
static GLenum floatType[] = { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 };
static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -584,7 +615,7 @@
return false;
}
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -681,7 +712,7 @@
bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -698,7 +729,7 @@
count = std::min(size - (int)uniformIndex[location].element, count);
- if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
+ if(targetUniform->type == GL_INT || IsSamplerUniform(targetUniform->type))
{
memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
v, sizeof(GLint) * count);
@@ -735,10 +766,9 @@
bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements)
{
static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
- static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -756,7 +786,7 @@
count = std::min(size - (int)uniformIndex[location].element, count);
int index = numElements - 1;
- if(targetUniform->type == intType[index] || targetUniform->type == uintType[index])
+ if(targetUniform->type == intType[index])
{
memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements,
v, numElements * sizeof(GLint)* count);
@@ -800,7 +830,7 @@
bool Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
{
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -817,7 +847,7 @@
count = std::min(size - (int)uniformIndex[location].element, count);
- if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
+ if(targetUniform->type == GL_UNSIGNED_INT)
{
memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint),
v, sizeof(GLuint)* count);
@@ -853,11 +883,10 @@
bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements)
{
- static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -875,7 +904,7 @@
count = std::min(size - (int)uniformIndex[location].element, count);
int index = numElements - 1;
- if(targetUniform->type == uintType[index] || targetUniform->type == intType[index])
+ if(targetUniform->type == uintType[index])
{
memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements,
v, numElements * sizeof(GLuint)* count);
@@ -919,7 +948,7 @@
bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
{
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -977,7 +1006,7 @@
bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
{
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -1026,7 +1055,7 @@
bool Program::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
{
- if(location < 0 || location >= (int)uniformIndex.size())
+ if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
{
return false;
}
@@ -1088,7 +1117,7 @@
GLint numUniforms = static_cast<GLint>(uniformIndex.size());
for(GLint location = 0; location < numUniforms; location++)
{
- if(uniformIndex[location].element != 0)
+ if((uniformIndex[location].element != 0) || (uniformIndex[location].index == GL_INVALID_INDEX))
{
continue;
}
@@ -1124,6 +1153,7 @@
case GL_FLOAT_MAT4: applyUniformMatrix4fv(device, location, size, f); break;
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -1294,21 +1324,36 @@
bool Program::linkVaryings()
{
- for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input)
+ glsl::VaryingList &psVaryings = fragmentShader->varyings;
+ glsl::VaryingList &vsVaryings = vertexShader->varyings;
+
+ for(auto const &input : psVaryings)
{
bool matched = false;
- for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); ++output)
+ for(auto const &output : vsVaryings)
{
- if(output->name == input->name)
+ if(output.name == input.name)
{
- if(output->type != input->type || output->size() != input->size())
+ if(output.type != input.type || output.size() != input.size())
{
- appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
+ appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output.name.c_str());
return false;
}
+ if((output.qualifier == EvqFlatOut) ^ (input.qualifier == EvqFlatIn))
+ {
+ appendToInfoLog("Interpolation qualifiers for %s differ between vertex and fragment shaders", output.name.c_str());
+
+ return false;
+ }
+
+ if(!areMatchingFields(input.fields, output.fields, input.name))
+ {
+ return false;
+ }
+
matched = true;
break;
}
@@ -1316,31 +1361,35 @@
if(!matched)
{
- appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());
+ // If a fragment varying is declared but not statically used, it's not an error to not have a matching vertex varying.
+ if(input.registerIndex >= 0)
+ {
+ appendToInfoLog("Fragment varying %s does not match any vertex varying", input.name.c_str());
- return false;
+ return false;
+ }
}
}
- glsl::VaryingList &psVaryings = fragmentShader->varyings;
- glsl::VaryingList &vsVaryings = vertexShader->varyings;
-
- for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); ++output)
+ for(auto const &output : vsVaryings)
{
bool matched = false;
- for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); ++input)
+ for(auto const &input : psVaryings)
{
- if(output->name == input->name)
+ if(output.name == input.name)
{
- int in = input->reg;
- int out = output->reg;
- int components = VariableRegisterSize(output->type);
- int registers = VariableRegisterCount(output->type) * output->size();
+ int in = input.registerIndex;
+ int out = output.registerIndex;
+ int components = VariableRegisterSize(output.type);
+ int registers = VariableRegisterCount(output.type) * output.size();
- ASSERT(in >= 0);
+ if(in < 0) // Fragment varying declared but not used
+ {
+ continue;
+ }
- if(in + registers > MAX_VARYING_VECTORS)
+ if(in + registers >= MAX_VARYING_VECTORS)
{
appendToInfoLog("Too many varyings");
return false;
@@ -1348,7 +1397,7 @@
if(out >= 0)
{
- if(out + registers > MAX_VARYING_VECTORS)
+ if(out + registers >= MAX_VARYING_VECTORS)
{
appendToInfoLog("Too many varyings");
return false;
@@ -1379,15 +1428,15 @@
{
std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, nullptr);
- if(tfVaryingName == output->name)
+ if(tfVaryingName == output.name)
{
- int out = output->reg;
- int components = VariableRegisterSize(output->type);
- int registers = VariableRegisterCount(output->type) * output->size();
+ int out = output.registerIndex;
+ int components = VariableRegisterSize(output.type);
+ int registers = VariableRegisterCount(output.type) * output.size();
if(out >= 0)
{
- if(out + registers > MAX_VARYING_VECTORS)
+ if(out + registers >= MAX_VARYING_VECTORS)
{
appendToInfoLog("Too many varyings");
return false;
@@ -1459,12 +1508,12 @@
totalComponents += componentCount;
- int reg = varying.reg;
+ int reg = varying.registerIndex;
if(hasSubscript)
{
reg += rowCount > 1 ? colCount * subscript : subscript;
}
- int col = varying.col;
+ int col = varying.column;
if(tfVaryingName == "gl_PointSize")
{
// Point size is stored in the y element of the vector, not the x element
@@ -1559,73 +1608,81 @@
unsigned int usedLocations = 0;
// Link attributes that have a binding location
- for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
+ for(auto const &attribute : vertexShader->activeAttributes)
{
- int location = getAttributeBinding(*attribute);
+ int location = (attributeBinding.find(attribute.name) != attributeBinding.end()) ? attributeBinding[attribute.name] : -1;
if(location != -1) // Set by glBindAttribLocation
{
- int rows = VariableRegisterCount(attribute->type);
+ int rows = VariableRegisterCount(attribute.type);
if(rows + location > MAX_VERTEX_ATTRIBS)
{
- appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
+ appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
return false;
}
// In GLSL 3.00, attribute aliasing produces a link error
// In GLSL 1.00, attribute aliasing is allowed
- if(egl::getClientVersion() >= 3)
+ if(vertexShader->getShaderVersion() >= 300)
{
- for(int i = 0; i < rows; i++)
+ for(auto const &it : linkedAttribute)
{
- if(!linkedAttribute[location + i].name.empty())
+ int itLocStart = getAttributeBinding(it);
+ ASSERT(itLocStart >= 0);
+ int itLocEnd = itLocStart + VariableRegisterCount(it.type);
+ for(int i = 0; i < rows; i++)
{
- appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute->name.c_str(), linkedAttribute[location].name.c_str(), location);
- return false;
+ int loc = location + i;
+ if((loc >= itLocStart) && (loc < itLocEnd))
+ {
+ appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), it.name.c_str(), location);
+ return false;
+ }
}
}
}
+ linkedAttributeLocation[attribute.name] = location;
+ linkedAttribute.push_back(attribute);
for(int i = 0; i < rows; i++)
{
- linkedAttribute[location + i] = *attribute;
usedLocations |= 1 << (location + i);
}
}
}
// Link attributes that don't have a binding location
- for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
+ for(auto const &attribute : vertexShader->activeAttributes)
{
- int location = getAttributeBinding(*attribute);
+ int location = (attributeBinding.find(attribute.name) != attributeBinding.end()) ? attributeBinding[attribute.name] : -1;
if(location == -1) // Not set by glBindAttribLocation
{
- int rows = VariableRegisterCount(attribute->type);
+ int rows = VariableRegisterCount(attribute.type);
int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
{
- appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
+ appendToInfoLog("Too many active attributes (%s)", attribute.name.c_str());
return false; // Fail to link
}
- for(int i = 0; i < rows; i++)
- {
- linkedAttribute[availableIndex + i] = *attribute;
- }
+ linkedAttributeLocation[attribute.name] = availableIndex;
+ linkedAttribute.push_back(attribute);
}
}
- for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
+ for(auto const &it : linkedAttribute)
{
- int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);
- int rows = std::max(VariableRegisterCount(linkedAttribute[attributeIndex].type), 1);
+ int location = getAttributeBinding(it);
+ ASSERT(location >= 0);
+ int index = vertexShader->getSemanticIndex(it.name);
+ int rows = std::max(VariableRegisterCount(it.type), 1);
for(int r = 0; r < rows; r++)
{
- attributeStream[attributeIndex++] = index++;
+ attributeStream[r + location] = index++;
}
}
@@ -1639,12 +1696,10 @@
return attribute.location;
}
- for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
+ std::map<std::string, GLuint>::const_iterator it = linkedAttributeLocation.find(attribute.name);
+ if(it != linkedAttributeLocation.end())
{
- if(attributeBinding[location].find(attribute.name.c_str()) != attributeBinding[location].end())
- {
- return location;
- }
+ return it->second;
}
return -1;
@@ -1652,12 +1707,8 @@
bool Program::linkUniforms(const Shader *shader)
{
- const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;
-
- for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
+ for(const auto &uniform : shader->activeUniforms)
{
- const glsl::Uniform &uniform = activeUniforms[uniformIndex];
-
unsigned int blockIndex = GL_INVALID_INDEX;
if(uniform.blockId >= 0)
{
@@ -1666,7 +1717,15 @@
blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name);
ASSERT(blockIndex != GL_INVALID_INDEX);
}
- if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex)))
+ if(!defineUniform(shader->getType(), uniform, Uniform::BlockInfo(uniform, blockIndex)))
+ {
+ return false;
+ }
+ }
+
+ for(const auto &uniformStruct : shader->activeUniformStructs)
+ {
+ if(!validateUniformStruct(shader->getType(), uniformStruct))
{
return false;
}
@@ -1675,11 +1734,11 @@
return true;
}
- bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo)
+ bool Program::defineUniform(GLenum shader, const glsl::Uniform &glslUniform, const Uniform::BlockInfo& blockInfo)
{
- if(IsSamplerUniform(type))
+ if(IsSamplerUniform(glslUniform.type))
{
- int index = registerIndex;
+ int index = glslUniform.registerIndex;
do
{
@@ -1689,9 +1748,9 @@
{
samplersVS[index].active = true;
- switch(type)
+ switch(glslUniform.type)
{
- default: UNREACHABLE(type);
+ default: UNREACHABLE(glslUniform.type);
case GL_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_SAMPLER_2D_SHADOW:
@@ -1703,6 +1762,7 @@
case GL_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_SAMPLER_3D_OES: samplersVS[index].textureType = TEXTURE_3D; break;
+ case GL_SAMPLER_2D_RECT_ARB: samplersVS[index].textureType = TEXTURE_2D_RECT; break;
case GL_SAMPLER_EXTERNAL_OES: samplersVS[index].textureType = TEXTURE_EXTERNAL; break;
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
@@ -1724,9 +1784,9 @@
{
samplersPS[index].active = true;
- switch(type)
+ switch(glslUniform.type)
{
- default: UNREACHABLE(type);
+ default: UNREACHABLE(glslUniform.type);
case GL_INT_SAMPLER_2D:
case GL_UNSIGNED_INT_SAMPLER_2D:
case GL_SAMPLER_2D_SHADOW:
@@ -1738,6 +1798,7 @@
case GL_INT_SAMPLER_3D:
case GL_UNSIGNED_INT_SAMPLER_3D:
case GL_SAMPLER_3D_OES: samplersPS[index].textureType = TEXTURE_3D; break;
+ case GL_SAMPLER_2D_RECT_ARB: samplersPS[index].textureType = TEXTURE_2D_RECT; break;
case GL_SAMPLER_EXTERNAL_OES: samplersPS[index].textureType = TEXTURE_EXTERNAL; break;
case GL_INT_SAMPLER_2D_ARRAY:
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
@@ -1757,31 +1818,36 @@
index++;
}
- while(index < registerIndex + static_cast<int>(arraySize));
+ while(index < glslUniform.registerIndex + static_cast<int>(glslUniform.arraySize));
}
Uniform *uniform = 0;
- GLint location = getUniformLocation(name);
+ GLint location = getUniformLocation(glslUniform.name);
if(location >= 0) // Previously defined, types must match
{
uniform = uniforms[uniformIndex[location].index];
- if(uniform->type != type)
+ if(uniform->type != glslUniform.type)
{
appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
return false;
}
- if(uniform->precision != precision)
+ if(uniform->precision != glslUniform.precision)
{
appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
return false;
}
+
+ if(!areMatchingFields(uniform->fields, glslUniform.fields, uniform->name))
+ {
+ return false;
+ }
}
else
{
- uniform = new Uniform(type, precision, name, arraySize, blockInfo);
+ uniform = new Uniform(glslUniform, blockInfo);
}
if(!uniform)
@@ -1791,28 +1857,28 @@
if(shader == GL_VERTEX_SHADER)
{
- uniform->vsRegisterIndex = registerIndex;
+ uniform->vsRegisterIndex = glslUniform.registerIndex;
}
else if(shader == GL_FRAGMENT_SHADER)
{
- uniform->psRegisterIndex = registerIndex;
+ uniform->psRegisterIndex = glslUniform.registerIndex;
}
else UNREACHABLE(shader);
- if(location == -1) // Not previously defined
+ if(!isUniformDefined(glslUniform.name))
{
uniforms.push_back(uniform);
- unsigned int index = static_cast<unsigned int>(uniforms.size() - 1);
+ unsigned int index = (blockInfo.index == -1) ? static_cast<unsigned int>(uniforms.size() - 1) : GL_INVALID_INDEX;
for(int i = 0; i < uniform->size(); i++)
{
- uniformIndex.push_back(UniformLocation(name, i, index));
+ uniformIndex.push_back(UniformLocation(glslUniform.name, i, index));
}
}
if(shader == GL_VERTEX_SHADER)
{
- if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
+ if(glslUniform.registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
{
appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
return false;
@@ -1820,7 +1886,7 @@
}
else if(shader == GL_FRAGMENT_SHADER)
{
- if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
+ if(glslUniform.registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
{
appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
return false;
@@ -1831,19 +1897,37 @@
return true;
}
+ bool Program::validateUniformStruct(GLenum shader, const glsl::Uniform &newUniformStruct)
+ {
+ for(const auto &uniformStruct : uniformStructs)
+ {
+ if(uniformStruct.name == newUniformStruct.name)
+ {
+ return areMatchingFields(uniformStruct.fields, newUniformStruct.fields, newUniformStruct.name);
+ }
+ }
+
+ uniformStructs.push_back(Uniform(newUniformStruct, Uniform::BlockInfo(newUniformStruct, -1)));
+
+ return true;
+ }
+
bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2)
{
// validate blocks for the same member types
if(block1.fields.size() != block2.fields.size())
{
+ appendToInfoLog("Types for interface block '%s' differ between vertex and fragment shaders", block1.name.c_str());
return false;
}
if(block1.arraySize != block2.arraySize)
{
+ appendToInfoLog("Array sizes differ for interface block '%s' between vertex and fragment shaders", block1.name.c_str());
return false;
}
if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout)
{
+ appendToInfoLog("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", block1.name.c_str());
return false;
}
const size_t numBlockMembers = block1.fields.size();
@@ -1851,14 +1935,68 @@
{
const glsl::Uniform& member1 = shader1->activeUniforms[block1.fields[blockMemberIndex]];
const glsl::Uniform& member2 = shader2->activeUniforms[block2.fields[blockMemberIndex]];
- if(member1.name != member2.name ||
- member1.arraySize != member2.arraySize ||
- member1.precision != member2.precision ||
- member1.type != member2.type)
+ if(member1.name != member2.name)
+ {
+ appendToInfoLog("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
+ blockMemberIndex, block1.name.c_str(), member1.name.c_str(), member2.name.c_str());
+ return false;
+ }
+ if(member1.arraySize != member2.arraySize)
+ {
+ appendToInfoLog("Array sizes for %s differ between vertex and fragment shaders", member1.name.c_str());
+ return false;
+ }
+ if(member1.precision != member2.precision)
+ {
+ appendToInfoLog("Precisions for %s differ between vertex and fragment shaders", member1.name.c_str());
+ return false;
+ }
+ if(member1.type != member2.type)
+ {
+ appendToInfoLog("Types for %s differ between vertex and fragment shaders", member1.name.c_str());
+ return false;
+ }
+ if(member1.blockInfo.isRowMajorMatrix != member2.blockInfo.isRowMajorMatrix)
+ {
+ appendToInfoLog("Matrix packings for %s differ between vertex and fragment shaders", member1.name.c_str());
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool Program::areMatchingFields(const std::vector<glsl::ShaderVariable>& fields1, const std::vector<glsl::ShaderVariable>& fields2, const std::string& name)
+ {
+ if(fields1.size() != fields2.size())
+ {
+ appendToInfoLog("Structure lengths for %s differ between vertex and fragment shaders", name.c_str());
+ return false;
+ }
+
+ for(size_t i = 0; i < fields1.size(); ++i)
+ {
+ if(fields1[i].name != fields2[i].name)
+ {
+ appendToInfoLog("Name mismatch for field '%d' of %s: ('%s', '%s')",
+ i, name.c_str(), fields1[i].name.c_str(), fields2[i].name.c_str());
+ return false;
+ }
+ if(fields1[i].type != fields2[i].type)
+ {
+ appendToInfoLog("Type for %s.%s differ between vertex and fragment shaders", name.c_str(), fields1[i].name.c_str());
+ return false;
+ }
+ if(fields1[i].arraySize != fields2[i].arraySize)
+ {
+ appendToInfoLog("Array size for %s.%s differ between vertex and fragment shaders", name.c_str(), fields1[i].name.c_str());
+ return false;
+ }
+ if(!areMatchingFields(fields1[i].fields, fields2[i].fields, fields1[i].name))
{
return false;
}
}
+
return true;
}
@@ -2478,9 +2616,11 @@
delete pixelBinary;
pixelBinary = 0;
+ linkedAttribute.clear();
+ linkedAttributeLocation.clear();
+
for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
- linkedAttribute[index].name.clear();
attributeStream[index] = -1;
}
@@ -2616,27 +2756,13 @@
void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
{
- // Skip over inactive attributes
- unsigned int activeAttribute = 0;
- unsigned int attribute;
- for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
- {
- if(linkedAttribute[attribute].name.empty())
- {
- continue;
- }
+ ASSERT(index < linkedAttribute.size());
- if(activeAttribute == index)
- {
- break;
- }
-
- activeAttribute++;
- }
+ std::vector<glsl::Attribute>::const_iterator it = linkedAttribute.begin() + index;
if(bufsize > 0)
{
- const char *string = linkedAttribute[attribute].name.c_str();
+ const char *string = it->name.c_str();
strncpy(name, string, bufsize);
name[bufsize - 1] = '\0';
@@ -2649,34 +2775,23 @@
*size = 1; // Always a single 'type' instance
- *type = linkedAttribute[attribute].type;
+ *type = it->type;
}
size_t Program::getActiveAttributeCount() const
{
- int count = 0;
-
- for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if(!linkedAttribute[attributeIndex].name.empty())
- {
- count++;
- }
- }
-
- return count;
+ return linkedAttribute.size();
}
GLint Program::getActiveAttributeMaxLength() const
{
int maxLength = 0;
- for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ std::vector<glsl::Attribute>::const_iterator it = linkedAttribute.begin();
+ std::vector<glsl::Attribute>::const_iterator itEnd = linkedAttribute.end();
+ for(; it != itEnd; ++it)
{
- if(!linkedAttribute[attributeIndex].name.empty())
- {
- maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);
- }
+ maxLength = std::max((int)(it->name.length() + 1), maxLength);
}
return maxLength;
@@ -2755,7 +2870,10 @@
void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const
{
- ASSERT(index < getActiveUniformBlockCount());
+ if(index >= getActiveUniformBlockCount())
+ {
+ return error(GL_INVALID_VALUE);
+ }
const UniformBlock &uniformBlock = *uniformBlocks[index];
diff --git a/src/OpenGL/libGLESv2/Program.h b/src/OpenGL/libGLESv2/Program.h
index 9d4621e..4d89d7a 100644
--- a/src/OpenGL/libGLESv2/Program.h
+++ b/src/OpenGL/libGLESv2/Program.h
@@ -26,6 +26,7 @@
#include <string>
#include <vector>
#include <set>
+#include <map>
namespace es2
{
@@ -48,8 +49,7 @@
bool isRowMajorMatrix;
};
- Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
- const BlockInfo &blockInfo);
+ Uniform(const glsl::Uniform &uniform, const BlockInfo &blockInfo);
~Uniform();
@@ -62,6 +62,7 @@
const std::string name;
const unsigned int arraySize;
const BlockInfo blockInfo;
+ std::vector<glsl::ShaderVariable> fields;
unsigned char *data;
bool dirty;
@@ -144,6 +145,7 @@
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
+ bool isUniformDefined(const std::string &name) const;
GLint getUniformLocation(const std::string &name) const;
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
@@ -232,7 +234,9 @@
bool linkUniforms(const Shader *shader);
bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader);
bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2);
- bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo);
+ bool areMatchingFields(const std::vector<glsl::ShaderVariable>& fields1, const std::vector<glsl::ShaderVariable>& fields2, const std::string& name);
+ bool validateUniformStruct(GLenum shader, const glsl::Uniform &newUniformStruct);
+ bool defineUniform(GLenum shader, const glsl::Uniform &uniform, const Uniform::BlockInfo& blockInfo);
bool defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block);
bool applyUniform(Device *device, GLint location, float* data);
bool applyUniform1bv(Device *device, GLint location, GLsizei count, const GLboolean *v);
@@ -278,8 +282,9 @@
sw::PixelShader *pixelBinary;
sw::VertexShader *vertexBinary;
- std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS];
- glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS];
+ std::map<std::string, GLuint> attributeBinding;
+ std::map<std::string, GLuint> linkedAttributeLocation;
+ std::vector<glsl::Attribute> linkedAttribute;
int attributeStream[MAX_VERTEX_ATTRIBS];
GLuint uniformBlockBindings[MAX_UNIFORM_BUFFER_BINDINGS];
@@ -300,6 +305,8 @@
typedef std::vector<Uniform*> UniformArray;
UniformArray uniforms;
+ typedef std::vector<Uniform> UniformStructArray;
+ UniformStructArray uniformStructs;
typedef std::vector<UniformLocation> UniformIndex;
UniformIndex uniformIndex;
typedef std::vector<UniformBlock*> UniformBlockArray;
diff --git a/src/OpenGL/libGLESv2/Renderbuffer.cpp b/src/OpenGL/libGLESv2/Renderbuffer.cpp
index 9b92698..48a61e9 100644
--- a/src/OpenGL/libGLESv2/Renderbuffer.cpp
+++ b/src/OpenGL/libGLESv2/Renderbuffer.cpp
@@ -22,6 +22,8 @@
#include "Texture.h"
#include "utilities.h"
+#include "compiler/Compiler.h"
+
namespace es2
{
RenderbufferInterface::RenderbufferInterface()
@@ -41,32 +43,32 @@
GLuint RenderbufferInterface::getRedSize() const
{
- return sw2es::GetRedSize(getInternalFormat());
+ return GetRedSize(getFormat());
}
GLuint RenderbufferInterface::getGreenSize() const
{
- return sw2es::GetGreenSize(getInternalFormat());
+ return GetGreenSize(getFormat());
}
GLuint RenderbufferInterface::getBlueSize() const
{
- return sw2es::GetBlueSize(getInternalFormat());
+ return GetBlueSize(getFormat());
}
GLuint RenderbufferInterface::getAlphaSize() const
{
- return sw2es::GetAlphaSize(getInternalFormat());
+ return GetAlphaSize(getFormat());
}
GLuint RenderbufferInterface::getDepthSize() const
{
- return sw2es::GetDepthSize(getInternalFormat());
+ return GetDepthSize(getFormat());
}
GLuint RenderbufferInterface::getStencilSize() const
{
- return sw2es::GetStencilSize(getInternalFormat());
+ return GetStencilSize(getFormat());
}
///// RenderbufferTexture2D Implementation ////////
@@ -122,30 +124,84 @@
return mTexture2D->getHeight(GL_TEXTURE_2D, mLevel);
}
-GLenum RenderbufferTexture2D::getFormat() const
+GLint RenderbufferTexture2D::getFormat() const
{
return mTexture2D->getFormat(GL_TEXTURE_2D, mLevel);
}
-sw::Format RenderbufferTexture2D::getInternalFormat() const
-{
- return mTexture2D->getInternalFormat(GL_TEXTURE_2D, mLevel);
-}
-
GLsizei RenderbufferTexture2D::getSamples() const
{
- return 0;
+ return 0; // Core OpenGL ES 3.0 does not support multisample textures.
+}
+
+///// RenderbufferTexture2DRect Implementation ////////
+
+RenderbufferTexture2DRect::RenderbufferTexture2DRect(Texture2DRect *texture)
+{
+ mTexture2DRect = texture;
+}
+
+RenderbufferTexture2DRect::~RenderbufferTexture2DRect()
+{
+ mTexture2DRect = NULL;
+}
+
+// Textures need to maintain their own reference count for references via
+// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
+void RenderbufferTexture2DRect::addProxyRef(const Renderbuffer *proxy)
+{
+ mTexture2DRect->addProxyRef(proxy);
+}
+
+void RenderbufferTexture2DRect::releaseProxy(const Renderbuffer *proxy)
+{
+ mTexture2DRect->releaseProxy(proxy);
+}
+
+// Increments refcount on image.
+// caller must release() the returned image
+egl::Image *RenderbufferTexture2DRect::getRenderTarget()
+{
+ return mTexture2DRect->getRenderTarget(GL_TEXTURE_RECTANGLE_ARB, 0);
+}
+
+// Increments refcount on image.
+// caller must release() the returned image
+egl::Image *RenderbufferTexture2DRect::createSharedImage()
+{
+ return mTexture2DRect->createSharedImage(GL_TEXTURE_RECTANGLE_ARB, 0);
+}
+
+bool RenderbufferTexture2DRect::isShared() const
+{
+ return mTexture2DRect->isShared(GL_TEXTURE_RECTANGLE_ARB, 0);
+}
+
+GLsizei RenderbufferTexture2DRect::getWidth() const
+{
+ return mTexture2DRect->getWidth(GL_TEXTURE_RECTANGLE_ARB, 0);
+}
+
+GLsizei RenderbufferTexture2DRect::getHeight() const
+{
+ return mTexture2DRect->getHeight(GL_TEXTURE_RECTANGLE_ARB, 0);
+}
+
+GLint RenderbufferTexture2DRect::getFormat() const
+{
+ return mTexture2DRect->getFormat(GL_TEXTURE_RECTANGLE_ARB, 0);
+}
+
+GLsizei RenderbufferTexture2DRect::getSamples() const
+{
+ return 0; // Core OpenGL ES 3.0 does not support multisample textures.
}
///// RenderbufferTexture3D Implementation ////////
-RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture, GLint level, GLint layer) : mLevel(level), mLayer(layer)
+RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture, GLint level) : mLevel(level)
{
mTexture3D = texture;
- if(mLayer != 0)
- {
- UNIMPLEMENTED();
- }
}
RenderbufferTexture3D::~RenderbufferTexture3D()
@@ -199,19 +255,14 @@
return mTexture3D->getDepth(mTexture3D->getTarget(), mLevel);
}
-GLenum RenderbufferTexture3D::getFormat() const
+GLint RenderbufferTexture3D::getFormat() const
{
return mTexture3D->getFormat(mTexture3D->getTarget(), mLevel);
}
-sw::Format RenderbufferTexture3D::getInternalFormat() const
-{
- return mTexture3D->getInternalFormat(mTexture3D->getTarget(), mLevel);
-}
-
GLsizei RenderbufferTexture3D::getSamples() const
{
- return 0;
+ return 0; // Core OpenGL ES 3.0 does not support multisample textures.
}
///// RenderbufferTextureCubeMap Implementation ////////
@@ -267,19 +318,14 @@
return mTextureCubeMap->getHeight(mTarget, mLevel);
}
-GLenum RenderbufferTextureCubeMap::getFormat() const
+GLint RenderbufferTextureCubeMap::getFormat() const
{
return mTextureCubeMap->getFormat(mTarget, mLevel);
}
-sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
-{
- return mTextureCubeMap->getInternalFormat(mTarget, mLevel);
-}
-
GLsizei RenderbufferTextureCubeMap::getSamples() const
{
- return 0;
+ return 0; // Core OpenGL ES 3.0 does not support multisample textures.
}
////// Renderbuffer Implementation //////
@@ -345,26 +391,16 @@
return mInstance->getDepth();
}
-GLint Renderbuffer::getLayer() const
-{
- return mInstance->getLayer();
-}
-
GLint Renderbuffer::getLevel() const
{
return mInstance->getLevel();
}
-GLenum Renderbuffer::getFormat() const
+GLint Renderbuffer::getFormat() const
{
return mInstance->getFormat();
}
-sw::Format Renderbuffer::getInternalFormat() const
-{
- return mInstance->getInternalFormat();
-}
-
GLuint Renderbuffer::getRedSize() const
{
return mInstance->getRedSize();
@@ -400,11 +436,6 @@
return mInstance->getSamples();
}
-void Renderbuffer::setLayer(GLint layer)
-{
- return mInstance->setLayer(layer);
-}
-
void Renderbuffer::setLevel(GLint level)
{
return mInstance->setLevel(level);
@@ -422,8 +453,7 @@
{
mWidth = 0;
mHeight = 0;
- format = GL_RGBA4;
- internalFormat = sw::FORMAT_A8B8G8R8;
+ format = GL_NONE;
mSamples = 0;
}
@@ -441,16 +471,11 @@
return mHeight;
}
-GLenum RenderbufferStorage::getFormat() const
+GLint RenderbufferStorage::getFormat() const
{
return format;
}
-sw::Format RenderbufferStorage::getInternalFormat() const
-{
- return internalFormat;
-}
-
GLsizei RenderbufferStorage::getSamples() const
{
return mSamples;
@@ -464,22 +489,24 @@
mWidth = renderTarget->getWidth();
mHeight = renderTarget->getHeight();
- internalFormat = renderTarget->getInternalFormat();
- format = sw2es::ConvertBackBufferFormat(internalFormat);
+ format = renderTarget->getFormat();
mSamples = renderTarget->getDepth() & ~1;
}
}
-Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
+Colorbuffer::Colorbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mRenderTarget(nullptr)
{
- Device *device = getDevice();
-
- sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
int supportedSamples = Context::getSupportedMultisampleCount(samples);
if(width > 0 && height > 0)
{
- mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
+ if(height > sw::OUTLINE_RESOLUTION)
+ {
+ error(GL_OUT_OF_MEMORY);
+ return;
+ }
+
+ mRenderTarget = egl::Image::create(width, height, internalformat, supportedSamples, false);
if(!mRenderTarget)
{
@@ -490,8 +517,7 @@
mWidth = width;
mHeight = height;
- this->format = format;
- internalFormat = requestedFormat;
+ format = internalformat;
mSamples = supportedSamples;
}
@@ -541,47 +567,24 @@
mWidth = depthStencil->getWidth();
mHeight = depthStencil->getHeight();
- internalFormat = depthStencil->getInternalFormat();
- format = sw2es::ConvertDepthStencilFormat(internalFormat);
+ format = depthStencil->getFormat();
mSamples = depthStencil->getDepth() & ~1;
}
}
-DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum requestedFormat, GLsizei samples) : mDepthStencil(nullptr)
+DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLenum internalformat, GLsizei samples) : mDepthStencil(nullptr)
{
- format = requestedFormat;
- switch(requestedFormat)
- {
- case GL_STENCIL_INDEX8:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH24_STENCIL8_OES:
- internalFormat = sw::FORMAT_D24S8;
- break;
- case GL_DEPTH32F_STENCIL8:
- internalFormat = sw::FORMAT_D32FS8_TEXTURE;
- break;
- case GL_DEPTH_COMPONENT16:
- internalFormat = sw::FORMAT_D16;
- break;
- case GL_DEPTH_COMPONENT32_OES:
- internalFormat = sw::FORMAT_D32;
- break;
- case GL_DEPTH_COMPONENT32F:
- internalFormat = sw::FORMAT_D32F;
- break;
- default:
- UNREACHABLE(requestedFormat);
- format = GL_DEPTH24_STENCIL8_OES;
- internalFormat = sw::FORMAT_D24S8;
- }
-
- Device *device = getDevice();
-
int supportedSamples = Context::getSupportedMultisampleCount(samples);
if(width > 0 && height > 0)
{
- mDepthStencil = device->createDepthStencilSurface(width, height, internalFormat, supportedSamples, false);
+ if(height > sw::OUTLINE_RESOLUTION)
+ {
+ error(GL_OUT_OF_MEMORY);
+ return;
+ }
+
+ mDepthStencil = egl::Image::create(width, height, internalformat, supportedSamples, false);
if(!mDepthStencil)
{
@@ -592,6 +595,7 @@
mWidth = width;
mHeight = height;
+ format = internalformat;
mSamples = supportedSamples;
}
@@ -637,7 +641,7 @@
{
}
-Depthbuffer::Depthbuffer(int width, int height, GLenum format, GLsizei samples) : DepthStencilbuffer(width, height, format, samples)
+Depthbuffer::Depthbuffer(int width, int height, GLenum internalformat, GLsizei samples) : DepthStencilbuffer(width, height, internalformat, samples)
{
}
diff --git a/src/OpenGL/libGLESv2/Renderbuffer.h b/src/OpenGL/libGLESv2/Renderbuffer.h
index 5e3f124..fa7123b 100644
--- a/src/OpenGL/libGLESv2/Renderbuffer.h
+++ b/src/OpenGL/libGLESv2/Renderbuffer.h
@@ -27,9 +27,11 @@
namespace es2
{
+
class Texture2D;
class Texture3D;
class TextureCubeMap;
+class Texture2DRect;
class Renderbuffer;
class Colorbuffer;
class DepthStencilbuffer;
@@ -51,13 +53,10 @@
virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0;
virtual GLsizei getDepth() const { return 1; }
- virtual GLint getLayer() const { return 0; }
virtual GLint getLevel() const { return 0; }
- virtual GLenum getFormat() const = 0;
- virtual sw::Format getInternalFormat() const = 0;
+ virtual GLint getFormat() const = 0;
virtual GLsizei getSamples() const = 0;
- virtual void setLayer(GLint) {}
virtual void setLevel(GLint) {}
GLuint getRedSize() const;
@@ -73,59 +72,77 @@
public:
RenderbufferTexture2D(Texture2D *texture, GLint level);
- virtual ~RenderbufferTexture2D();
+ ~RenderbufferTexture2D() override;
- virtual void addProxyRef(const Renderbuffer *proxy);
- virtual void releaseProxy(const Renderbuffer *proxy);
+ void addProxyRef(const Renderbuffer *proxy) override;
+ void releaseProxy(const Renderbuffer *proxy) override;
- virtual egl::Image *getRenderTarget();
- virtual egl::Image *createSharedImage();
- virtual bool isShared() const;
+ egl::Image *getRenderTarget() override;
+ egl::Image *createSharedImage() override;
+ bool isShared() const override;
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLint getLevel() const { return mLevel; }
- virtual GLenum getFormat() const;
- virtual sw::Format getInternalFormat() const;
- virtual GLsizei getSamples() const;
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLint getLevel() const override { return mLevel; }
+ GLint getFormat() const override;
+ GLsizei getSamples() const override;
- virtual void setLevel(GLint level) { mLevel = level; }
+ void setLevel(GLint level) override { mLevel = level; }
private:
gl::BindingPointer<Texture2D> mTexture2D;
GLint mLevel;
};
+class RenderbufferTexture2DRect : public RenderbufferInterface
+{
+public:
+ RenderbufferTexture2DRect(Texture2DRect *texture);
+
+ ~RenderbufferTexture2DRect() override;
+
+ void addProxyRef(const Renderbuffer *proxy) override;
+ void releaseProxy(const Renderbuffer *proxy) override;
+
+ egl::Image *getRenderTarget() override;
+ egl::Image *createSharedImage() override;
+ bool isShared() const override;
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLint getFormat() const override;
+ GLsizei getSamples() const override;
+
+private:
+ gl::BindingPointer<Texture2DRect> mTexture2DRect;
+};
+
class RenderbufferTexture3D : public RenderbufferInterface
{
public:
- RenderbufferTexture3D(Texture3D *texture, GLint level, GLint layer);
+ RenderbufferTexture3D(Texture3D *texture, GLint level);
- virtual ~RenderbufferTexture3D();
+ ~RenderbufferTexture3D() override;
- virtual void addProxyRef(const Renderbuffer *proxy);
- virtual void releaseProxy(const Renderbuffer *proxy);
+ void addProxyRef(const Renderbuffer *proxy) override;
+ void releaseProxy(const Renderbuffer *proxy) override;
- virtual egl::Image *getRenderTarget();
- virtual egl::Image *createSharedImage();
- virtual bool isShared() const;
+ egl::Image *getRenderTarget() override;
+ egl::Image *createSharedImage() override;
+ bool isShared() const override;
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLsizei getDepth() const;
- virtual GLint getLayer() const { return mLayer; }
- virtual GLint getLevel() const { return mLevel; }
- virtual GLenum getFormat() const;
- virtual sw::Format getInternalFormat() const;
- virtual GLsizei getSamples() const;
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLint getLevel() const override { return mLevel; }
+ GLint getFormat() const override;
+ GLsizei getSamples() const override;
- virtual void setLayer(GLint layer) { mLayer = layer; }
- virtual void setLevel(GLint level) { mLevel = level; }
+ void setLevel(GLint level) override { mLevel = level; }
private:
gl::BindingPointer<Texture3D> mTexture3D;
GLint mLevel;
- GLint mLayer;
};
class RenderbufferTextureCubeMap : public RenderbufferInterface
@@ -133,23 +150,22 @@
public:
RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level);
- virtual ~RenderbufferTextureCubeMap();
+ ~RenderbufferTextureCubeMap() override;
- virtual void addProxyRef(const Renderbuffer *proxy);
- virtual void releaseProxy(const Renderbuffer *proxy);
+ void addProxyRef(const Renderbuffer *proxy) override;
+ void releaseProxy(const Renderbuffer *proxy) override;
- virtual egl::Image *getRenderTarget();
- virtual egl::Image *createSharedImage();
- virtual bool isShared() const;
+ egl::Image *getRenderTarget() override;
+ egl::Image *createSharedImage() override;
+ bool isShared() const override;
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLint getLevel() const { return mLevel; }
- virtual GLenum getFormat() const;
- virtual sw::Format getInternalFormat() const;
- virtual GLsizei getSamples() const;
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLint getLevel() const override { return mLevel; }
+ GLint getFormat() const override;
+ GLsizei getSamples() const override;
- virtual void setLevel(GLint level) { mLevel = level; }
+ void setLevel(GLint level) override { mLevel = level; }
private:
gl::BindingPointer<TextureCubeMap> mTextureCubeMap;
@@ -165,23 +181,21 @@
public:
RenderbufferStorage();
- virtual ~RenderbufferStorage() = 0;
+ ~RenderbufferStorage() override = 0;
- virtual egl::Image *getRenderTarget() = 0;
- virtual egl::Image *createSharedImage() = 0;
- virtual bool isShared() const = 0;
+ egl::Image *getRenderTarget() override = 0;
+ egl::Image *createSharedImage() override = 0;
+ bool isShared() const override = 0;
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLenum getFormat() const;
- virtual sw::Format getInternalFormat() const;
- virtual GLsizei getSamples() const;
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLint getFormat() const override;
+ GLsizei getSamples() const override;
protected:
GLsizei mWidth;
GLsizei mHeight;
GLenum format;
- sw::Format internalFormat;
GLsizei mSamples;
};
@@ -193,14 +207,14 @@
public:
Renderbuffer(GLuint name, RenderbufferInterface *storage);
- virtual ~Renderbuffer();
+ ~Renderbuffer() override;
// These functions from Object are overloaded here because
// Textures need to maintain their own count of references to them via
// Renderbuffers/RenderbufferTextures. These functions invoke those
// reference counting functions on the RenderbufferInterface.
- virtual void addRef();
- virtual void release();
+ void addRef() override;
+ void release() override;
egl::Image *getRenderTarget();
virtual egl::Image *createSharedImage();
@@ -209,10 +223,8 @@
GLsizei getWidth() const;
GLsizei getHeight() const;
GLsizei getDepth() const;
- GLint getLayer() const;
GLint getLevel() const;
- GLenum getFormat() const;
- sw::Format getInternalFormat() const;
+ GLint getFormat() const;
GLuint getRedSize() const;
GLuint getGreenSize() const;
GLuint getBlueSize() const;
@@ -221,7 +233,6 @@
GLuint getStencilSize() const;
GLsizei getSamples() const;
- void setLayer(GLint layer);
void setLevel(GLint level);
void setStorage(RenderbufferStorage *newStorage);
@@ -233,13 +244,13 @@
{
public:
explicit Colorbuffer(egl::Image *renderTarget);
- Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+ Colorbuffer(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
- virtual ~Colorbuffer();
+ ~Colorbuffer() override;
- virtual egl::Image *getRenderTarget();
- virtual egl::Image *createSharedImage();
- virtual bool isShared() const;
+ egl::Image *getRenderTarget() override;
+ egl::Image *createSharedImage() override;
+ bool isShared() const override;
private:
egl::Image *mRenderTarget;
@@ -249,13 +260,13 @@
{
public:
explicit DepthStencilbuffer(egl::Image *depthStencil);
- DepthStencilbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+ DepthStencilbuffer(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
~DepthStencilbuffer();
- virtual egl::Image *getRenderTarget();
- virtual egl::Image *createSharedImage();
- virtual bool isShared() const;
+ egl::Image *getRenderTarget() override;
+ egl::Image *createSharedImage() override;
+ bool isShared() const override;
protected:
egl::Image *mDepthStencil;
@@ -265,9 +276,9 @@
{
public:
explicit Depthbuffer(egl::Image *depthStencil);
- Depthbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+ Depthbuffer(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
- virtual ~Depthbuffer();
+ ~Depthbuffer() override;
};
class Stencilbuffer : public DepthStencilbuffer
@@ -276,7 +287,7 @@
explicit Stencilbuffer(egl::Image *depthStencil);
Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
- virtual ~Stencilbuffer();
+ ~Stencilbuffer() override;
};
}
diff --git a/src/OpenGL/libGLESv2/ResourceManager.cpp b/src/OpenGL/libGLESv2/ResourceManager.cpp
index e5c5492..51a7bc1 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.cpp
+++ b/src/OpenGL/libGLESv2/ResourceManager.cpp
@@ -308,6 +308,10 @@
{
textureObject = new Texture2DArray(texture);
}
+ else if(type == TEXTURE_2D_RECT)
+ {
+ textureObject = new Texture2DRect(texture);
+ }
else
{
UNREACHABLE(type);
@@ -324,7 +328,7 @@
{
if(handle != 0 && !getRenderbuffer(handle))
{
- Renderbuffer *renderbufferObject = new Renderbuffer(handle, new Colorbuffer(0, 0, GL_RGBA4_OES, 0));
+ Renderbuffer *renderbufferObject = new Renderbuffer(handle, new Colorbuffer(0, 0, GL_NONE, 0));
renderbufferObject->addRef();
mRenderbufferNameSpace.insert(handle, renderbufferObject);
diff --git a/src/OpenGL/libGLESv2/ResourceManager.h b/src/OpenGL/libGLESv2/ResourceManager.h
index efd0e20..c076653 100644
--- a/src/OpenGL/libGLESv2/ResourceManager.h
+++ b/src/OpenGL/libGLESv2/ResourceManager.h
@@ -40,6 +40,7 @@
TEXTURE_3D,
TEXTURE_2D_ARRAY,
TEXTURE_CUBE,
+ TEXTURE_2D_RECT,
TEXTURE_EXTERNAL,
TEXTURE_TYPE_COUNT,
diff --git a/src/OpenGL/libGLESv2/Sampler.h b/src/OpenGL/libGLESv2/Sampler.h
index 12ed6da..0dbf8c9 100644
--- a/src/OpenGL/libGLESv2/Sampler.h
+++ b/src/OpenGL/libGLESv2/Sampler.h
@@ -50,8 +50,8 @@
void setWrapR(GLenum wrapR) { mWrapModeR = wrapR; }
void setMinLod(GLfloat minLod) { mMinLod = minLod; }
void setMaxLod(GLfloat maxLod) { mMaxLod = maxLod; }
- void setComparisonMode(GLenum comparisonMode) { mCompareMode = comparisonMode; }
- void setComparisonFunc(GLenum comparisonFunc) { mCompareFunc = comparisonFunc; }
+ void setCompareMode(GLenum compareMode) { mCompareMode = compareMode; }
+ void setCompareFunc(GLenum compareFunc) { mCompareFunc = compareFunc; }
GLenum getMinFilter() const { return mMinFilter; }
GLenum getMagFilter() const { return mMagFilter; }
@@ -60,8 +60,8 @@
GLenum getWrapR() const { return mWrapModeR; }
GLfloat getMinLod() const { return mMinLod; }
GLfloat getMaxLod() const { return mMaxLod; }
- GLenum getComparisonMode() const { return mCompareMode; }
- GLenum getComparisonFunc() const { return mCompareFunc; }
+ GLenum getCompareMode() const { return mCompareMode; }
+ GLenum getCompareFunc() const { return mCompareFunc; }
private:
GLenum mMinFilter;
diff --git a/src/OpenGL/libGLESv2/Shader.cpp b/src/OpenGL/libGLESv2/Shader.cpp
index df25d29..9cb6bd5 100644
--- a/src/OpenGL/libGLESv2/Shader.cpp
+++ b/src/OpenGL/libGLESv2/Shader.cpp
@@ -181,7 +181,8 @@
resources.OES_fragment_precision_high = 1;
resources.OES_EGL_image_external = 1;
resources.EXT_draw_buffers = 1;
- resources.MaxCallStackDepth = 16;
+ resources.ARB_texture_rectangle = 1;
+ resources.MaxCallStackDepth = 64;
assembler->Init(resources);
return assembler;
@@ -215,16 +216,22 @@
if(false)
{
static int serial = 1;
- char buffer[256];
- sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
- FILE *file = fopen(buffer, "wt");
- fprintf(file, "%s", mSource);
- fclose(file);
+
+ if(false)
+ {
+ char buffer[256];
+ sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
+ FILE *file = fopen(buffer, "wt");
+ fprintf(file, "%s", mSource);
+ fclose(file);
+ }
+
getShader()->print("shader-output-%d-%d.txt", getName(), serial);
+
serial++;
}
- int shaderVersion = compiler->getShaderVersion();
+ shaderVersion = compiler->getShaderVersion();
int clientVersion = es2::getContext()->getClientVersion();
if(shaderVersion >= 300 && clientVersion < 3)
@@ -383,15 +390,15 @@
return GL_VERTEX_SHADER;
}
-int VertexShader::getSemanticIndex(const std::string &attributeName)
+int VertexShader::getSemanticIndex(const std::string &attributeName) const
{
if(!attributeName.empty())
{
- for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
+ for(const auto &attribute : activeAttributes)
{
- if(attribute->name == attributeName)
+ if(attribute.name == attributeName)
{
- return attribute->registerIndex;
+ return attribute.registerIndex;
}
}
}
diff --git a/src/OpenGL/libGLESv2/Shader.h b/src/OpenGL/libGLESv2/Shader.h
index 0c29e4b..63d50ae 100644
--- a/src/OpenGL/libGLESv2/Shader.h
+++ b/src/OpenGL/libGLESv2/Shader.h
@@ -99,7 +99,7 @@
~VertexShader();
virtual GLenum getType() const;
- int getSemanticIndex(const std::string &attributeName);
+ int getSemanticIndex(const std::string &attributeName) const;
virtual sw::Shader *getShader() const;
virtual sw::VertexShader *getVertexShader() const;
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index b0a46a5..dc0e807 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -22,6 +22,7 @@
#include "mathutil.h"
#include "Framebuffer.h"
#include "Device.hpp"
+#include "Shader.h"
#include "libEGL/Display.h"
#include "common/Surface.hpp"
#include "common/debug.h"
@@ -74,7 +75,7 @@
case GL_LINEAR_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
- if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+ if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
{
return false;
}
@@ -109,7 +110,7 @@
{
case GL_REPEAT:
case GL_MIRRORED_REPEAT:
- if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+ if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
{
return false;
}
@@ -129,7 +130,7 @@
{
case GL_REPEAT:
case GL_MIRRORED_REPEAT:
- if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+ if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
{
return false;
}
@@ -149,7 +150,7 @@
{
case GL_REPEAT:
case GL_MIRRORED_REPEAT:
- if(getTarget() == GL_TEXTURE_EXTERNAL_OES)
+ if((getTarget() == GL_TEXTURE_EXTERNAL_OES) || (getTarget() == GL_TEXTURE_RECTANGLE_ARB))
{
return false;
}
@@ -182,6 +183,11 @@
bool Texture::setBaseLevel(GLint baseLevel)
{
+ if(baseLevel < 0)
+ {
+ return false;
+ }
+
mBaseLevel = baseLevel;
return true;
}
@@ -310,85 +316,6 @@
}
}
-GLenum Texture::getMinFilter() const
-{
- return mMinFilter;
-}
-
-GLenum Texture::getMagFilter() const
-{
- return mMagFilter;
-}
-
-GLenum Texture::getWrapS() const
-{
- return mWrapS;
-}
-
-GLenum Texture::getWrapT() const
-{
- return mWrapT;
-}
-
-GLenum Texture::getWrapR() const
-{
- return mWrapR;
-}
-
-GLfloat Texture::getMaxAnisotropy() const
-{
- return mMaxAnisotropy;
-}
-
-GLint Texture::getBaseLevel() const
-{
- return mBaseLevel;
-}
-GLenum Texture::getCompareFunc() const
-{
- return mCompareFunc;
-}
-GLenum Texture::getCompareMode() const
-{
- return mCompareMode;
-}
-GLboolean Texture::getImmutableFormat() const
-{
- return mImmutableFormat;
-}
-GLsizei Texture::getImmutableLevels() const
-{
- return mImmutableLevels;
-}
-GLint Texture::getMaxLevel() const
-{
- return mMaxLevel;
-}
-GLfloat Texture::getMaxLOD() const
-{
- return mMaxLOD;
-}
-GLfloat Texture::getMinLOD() const
-{
- return mMinLOD;
-}
-GLenum Texture::getSwizzleR() const
-{
- return mSwizzleR;
-}
-GLenum Texture::getSwizzleG() const
-{
- return mSwizzleG;
-}
-GLenum Texture::getSwizzleB() const
-{
- return mSwizzleB;
-}
-GLenum Texture::getSwizzleA() const
-{
- return mSwizzleA;
-}
-
GLsizei Texture::getDepth(GLenum target, GLint level) const
{
return 1;
@@ -406,49 +333,34 @@
return image;
}
-void Texture::setImage(egl::Context *context, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image)
+void Texture::setImage(GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image)
{
if(pixels && image)
{
GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;
- image->loadImageData(context, 0, 0, 0, image->getWidth(), image->getHeight(), depth, format, type, unpackInfo, pixels);
+ image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), depth, format, type, unpackParameters, pixels);
}
}
void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image)
{
- if(pixels && image)
+ if(pixels && image && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
{
GLsizei depth = (getTarget() == GL_TEXTURE_3D_OES || getTarget() == GL_TEXTURE_2D_ARRAY) ? image->getDepth() : 1;
image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), depth, imageSize, pixels);
}
}
-void Texture::subImage(egl::Context *context, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image)
+void Texture::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image)
{
if(!image)
{
return error(GL_INVALID_OPERATION);
}
- if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())
+ if(pixels && width > 0 && height > 0 && depth > 0)
{
- return error(GL_INVALID_VALUE);
- }
-
- if(IsCompressed(image->getFormat(), egl::getClientVersion()))
- {
- return error(GL_INVALID_OPERATION);
- }
-
- if(format != image->getFormat())
- {
- return error(GL_INVALID_OPERATION);
- }
-
- if(pixels)
- {
- image->loadImageData(context, xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels);
+ image->loadImageData(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackParameters, pixels);
}
}
@@ -459,28 +371,23 @@
return error(GL_INVALID_OPERATION);
}
- if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())
- {
- return error(GL_INVALID_VALUE);
- }
-
- if(format != image->getFormat())
- {
- return error(GL_INVALID_OPERATION);
- }
-
- if(pixels)
+ if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
{
image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, imageSize, pixels);
}
}
-bool Texture::copy(egl::Image *source, const sw::SliceRect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest)
+bool Texture::copy(egl::Image *source, const sw::SliceRect &sourceRect, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest)
{
Device *device = getDevice();
sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), zoffset);
- bool success = device->stretchRect(source, &sourceRect, dest, &destRect, Device::ALL_BUFFERS);
+ sw::SliceRectF sourceRectF(static_cast<float>(sourceRect.x0),
+ static_cast<float>(sourceRect.y0),
+ static_cast<float>(sourceRect.x1),
+ static_cast<float>(sourceRect.y1),
+ sourceRect.slice);
+ bool success = device->stretchRect(source, &sourceRectF, dest, &destRect, Device::ALL_BUFFERS);
if(!success)
{
@@ -592,78 +499,54 @@
GLsizei Texture2D::getWidth(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getWidth() : 0;
}
GLsizei Texture2D::getHeight(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getHeight() : 0;
}
-GLenum Texture2D::getFormat(GLenum target, GLint level) const
+GLint Texture2D::getFormat(GLenum target, GLint level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
return image[level] ? image[level]->getFormat() : GL_NONE;
}
-GLenum Texture2D::getType(GLenum target, GLint level) const
-{
- ASSERT(target == GL_TEXTURE_2D);
- return image[level] ? image[level]->getType() : GL_NONE;
-}
-
-sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const
-{
- ASSERT(target == GL_TEXTURE_2D);
- return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
-}
-
-int Texture2D::getLevelCount() const
+int Texture2D::getTopLevel() const
{
ASSERT(isSamplerComplete());
- int levels = 0;
+ int level = mBaseLevel;
- while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+ while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
{
- levels++;
+ level++;
}
- return levels;
+ return level - 1;
}
-void Texture2D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
if(image[level])
{
image[level]->release();
}
- image[level] = egl::Image::create(this, width, height, format, type);
+ image[level] = egl::Image::create(this, width, height, internalformat);
if(!image[level])
{
return error(GL_OUT_OF_MEMORY);
}
- Texture::setImage(context, format, type, unpackInfo, pixels, image[level]);
+ Texture::setImage(format, type, unpackParameters, pixels, image[level]);
}
void Texture2D::bindTexImage(gl::Surface *surface)
{
- switch(surface->getInternalFormat())
- {
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- break;
- default:
- UNIMPLEMENTED();
- return;
- }
-
for(int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
if(image[level])
@@ -689,6 +572,12 @@
image[level] = nullptr;
}
}
+
+ if(mSurface)
+ {
+ mSurface->setBoundTexture(nullptr);
+ mSurface = nullptr;
+ }
}
void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
@@ -698,8 +587,7 @@
image[level]->release();
}
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
- image[level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
+ image[level] = egl::Image::create(this, width, height, format);
if(!image[level])
{
@@ -709,9 +597,9 @@
Texture::setCompressedImage(imageSize, pixels, image[level]);
}
-void Texture2D::subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
- Texture::subImage(context, xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels, image[level]);
+ Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackParameters, pixels, image[level]);
}
void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
@@ -719,9 +607,9 @@
Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[level]);
}
-void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+void Texture2D::copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
- egl::Image *renderTarget = source->getRenderTarget(0);
+ egl::Image *renderTarget = source->getRenderTarget();
if(!renderTarget)
{
@@ -734,8 +622,7 @@
image[level]->release();
}
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
- image[level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
+ image[level] = egl::Image::create(this, width, height, internalformat);
if(!image[level])
{
@@ -744,24 +631,16 @@
if(width != 0 && height != 0)
{
- Renderbuffer* renderbuffer = source->getReadColorbuffer();
-
- if(!renderbuffer)
- {
- ERR("Failed to retrieve the source colorbuffer.");
- return;
- }
-
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
- sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
+ sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
- copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[level]);
+ copy(renderTarget, sourceRect, 0, 0, 0, image[level]);
}
renderTarget->release();
}
-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
if(!image[level])
{
@@ -773,28 +652,23 @@
return error(GL_INVALID_VALUE);
}
- egl::Image *renderTarget = source->getRenderTarget(0);
-
- if(!renderTarget)
+ if(width > 0 && height > 0)
{
- ERR("Failed to retrieve the render target.");
- return error(GL_OUT_OF_MEMORY);
+ egl::Image *renderTarget = source->getRenderTarget();
+
+ if(!renderTarget)
+ {
+ ERR("Failed to retrieve the render target.");
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
+ sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
+
+ copy(renderTarget, sourceRect, xoffset, yoffset, zoffset, image[level]);
+
+ renderTarget->release();
}
-
- Renderbuffer* renderbuffer = source->getReadColorbuffer();
-
- if(!renderbuffer)
- {
- ERR("Failed to retrieve the source colorbuffer.");
- return;
- }
-
- sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
- sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
-
- copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
-
- renderTarget->release();
}
void Texture2D::setSharedImage(egl::Image *sharedImage)
@@ -814,16 +688,16 @@
image[0] = sharedImage;
}
-// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+// Tests for 2D texture sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool Texture2D::isSamplerComplete() const
{
- if(!image[0])
+ if(!image[mBaseLevel])
{
return false;
}
- GLsizei width = image[0]->getWidth();
- GLsizei height = image[0]->getHeight();
+ GLsizei width = image[mBaseLevel]->getWidth();
+ GLsizei height = image[mBaseLevel]->getHeight();
if(width <= 0 || height <= 0)
{
@@ -841,13 +715,19 @@
return true;
}
-// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+// Tests for 2D texture (mipmap) completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool Texture2D::isMipmapComplete() const
{
+ if(mBaseLevel > mMaxLevel)
+ {
+ return false;
+ }
+
GLsizei width = image[mBaseLevel]->getWidth();
GLsizei height = image[mBaseLevel]->getHeight();
-
- int q = std::min(log2(std::max(width, height)), mMaxLevel);
+ int maxsize = std::max(width, height);
+ int p = log2(maxsize) + mBaseLevel;
+ int q = std::min(p, mMaxLevel);
for(int level = mBaseLevel + 1; level <= q; level++)
{
@@ -856,22 +736,19 @@
return false;
}
- if(image[level]->getFormat() != image[0]->getFormat())
+ if(image[level]->getFormat() != image[mBaseLevel]->getFormat())
{
return false;
}
- if(image[level]->getType() != image[0]->getType())
+ int i = level - mBaseLevel;
+
+ if(image[level]->getWidth() != std::max(1, width >> i))
{
return false;
}
- if(image[level]->getWidth() != std::max(1, width >> level))
- {
- return false;
- }
-
- if(image[level]->getHeight() != std::max(1, height >> level))
+ if(image[level]->getHeight() != std::max(1, height >> i))
{
return false;
}
@@ -892,21 +769,20 @@
void Texture2D::generateMipmaps()
{
- if(!image[0])
- {
- return; // FIXME: error?
- }
+ ASSERT(image[mBaseLevel]);
- unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+ int maxsize = std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight());
+ int p = log2(maxsize) + mBaseLevel;
+ int q = std::min(p, mMaxLevel);
- for(unsigned int i = 1; i <= q; i++)
+ for(int i = mBaseLevel + 1; i <= q; i++)
{
if(image[i])
{
image[i]->release();
}
- image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
+ image[i] = egl::Image::create(this, std::max(image[mBaseLevel]->getWidth() >> i, 1), std::max(image[mBaseLevel]->getHeight() >> i, 1), image[mBaseLevel]->getFormat());
if(!image[i])
{
@@ -922,9 +798,9 @@
return image[level];
}
-Renderbuffer *Texture2D::getRenderbuffer(GLenum target, GLint level, GLint layer)
+Renderbuffer *Texture2D::getRenderbuffer(GLenum target, GLint level)
{
- if(target != GL_TEXTURE_2D)
+ if(target != getTarget())
{
return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
}
@@ -943,7 +819,7 @@
egl::Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if(image[level])
@@ -956,7 +832,7 @@
bool Texture2D::isShared(GLenum target, unsigned int level) const
{
- ASSERT(target == GL_TEXTURE_2D);
+ ASSERT(target == getTarget());
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if(mSurface) // Bound to an EGLSurface
@@ -972,6 +848,35 @@
return image[level]->isShared();
}
+Texture2DRect::Texture2DRect(GLuint name) : Texture2D(name)
+{
+ mMinFilter = GL_LINEAR;
+ mMagFilter = GL_LINEAR;
+ mWrapS = GL_CLAMP_TO_EDGE;
+ mWrapT = GL_CLAMP_TO_EDGE;
+ mWrapR = GL_CLAMP_TO_EDGE;
+}
+
+GLenum Texture2DRect::getTarget() const
+{
+ return GL_TEXTURE_RECTANGLE_ARB;
+}
+
+Renderbuffer *Texture2DRect::getRenderbuffer(GLenum target, GLint level)
+{
+ if((target != getTarget()) || (level != 0))
+ {
+ return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
+ }
+
+ if(!mColorbufferProxy)
+ {
+ mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2DRect(this));
+ }
+
+ return mColorbufferProxy;
+}
+
TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
{
for(int f = 0; f < 6; f++)
@@ -1087,35 +992,23 @@
return image[face][level] ? image[face][level]->getHeight() : 0;
}
-GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const
+GLint TextureCubeMap::getFormat(GLenum target, GLint level) const
{
int face = CubeFaceIndex(target);
return image[face][level] ? image[face][level]->getFormat() : 0;
}
-GLenum TextureCubeMap::getType(GLenum target, GLint level) const
-{
- int face = CubeFaceIndex(target);
- return image[face][level] ? image[face][level]->getType() : 0;
-}
-
-sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
-{
- int face = CubeFaceIndex(target);
- return image[face][level] ? image[face][level]->getInternalFormat() : sw::FORMAT_NULL;
-}
-
-int TextureCubeMap::getLevelCount() const
+int TextureCubeMap::getTopLevel() const
{
ASSERT(isSamplerComplete());
- int levels = 0;
+ int level = mBaseLevel;
- while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][levels])
+ while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][level])
{
- levels++;
+ level++;
}
- return levels;
+ return level - 1;
}
void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
@@ -1127,8 +1020,8 @@
image[face][level]->release();
}
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
- image[face][level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
+ int border = (egl::getClientVersion() >= 3) ? 1 : 0;
+ image[face][level] = egl::Image::create(this, width, height, 1, border, format);
if(!image[face][level])
{
@@ -1138,9 +1031,9 @@
Texture::setCompressedImage(imageSize, pixels, image[face][level]);
}
-void TextureCubeMap::subImage(egl::Context *context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
- Texture::subImage(context, xoffset, yoffset, 0, width, height, 1, format, type, unpackInfo, pixels, image[CubeFaceIndex(target)][level]);
+ Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpackParameters, pixels, image[CubeFaceIndex(target)][level]);
}
void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
@@ -1148,18 +1041,18 @@
Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);
}
-// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.
+// Tests for cube map sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 161.
bool TextureCubeMap::isSamplerComplete() const
{
for(int face = 0; face < 6; face++)
{
- if(!image[face][0])
+ if(!image[face][mBaseLevel])
{
return false;
}
}
- int size = image[0][0]->getWidth();
+ int size = image[0][mBaseLevel]->getWidth();
if(size <= 0)
{
@@ -1184,7 +1077,7 @@
return true;
}
-// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+// Tests for cube texture completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool TextureCubeMap::isCubeComplete() const
{
if(image[0][mBaseLevel]->getWidth() <= 0 || image[0][mBaseLevel]->getHeight() != image[0][mBaseLevel]->getWidth())
@@ -1196,8 +1089,7 @@
{
if(image[face][mBaseLevel]->getWidth() != image[0][mBaseLevel]->getWidth() ||
image[face][mBaseLevel]->getWidth() != image[0][mBaseLevel]->getHeight() ||
- image[face][mBaseLevel]->getFormat() != image[0][mBaseLevel]->getFormat() ||
- image[face][mBaseLevel]->getType() != image[0][mBaseLevel]->getType())
+ image[face][mBaseLevel]->getFormat() != image[0][mBaseLevel]->getFormat())
{
return false;
}
@@ -1208,13 +1100,19 @@
bool TextureCubeMap::isMipmapCubeComplete() const
{
+ if(mBaseLevel > mMaxLevel)
+ {
+ return false;
+ }
+
if(!isCubeComplete())
{
return false;
}
GLsizei size = image[0][mBaseLevel]->getWidth();
- int q = std::min(log2(size), mMaxLevel);
+ int p = log2(size) + mBaseLevel;
+ int q = std::min(p, mMaxLevel);
for(int face = 0; face < 6; face++)
{
@@ -1230,12 +1128,9 @@
return false;
}
- if(image[face][level]->getType() != image[0][mBaseLevel]->getType())
- {
- return false;
- }
+ int i = level - mBaseLevel;
- if(image[face][level]->getWidth() != std::max(1, size >> level))
+ if(image[face][level]->getWidth() != std::max(1, size >> i))
{
return false;
}
@@ -1245,6 +1140,69 @@
return true;
}
+void TextureCubeMap::updateBorders(int level)
+{
+ egl::Image *posX = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_POSITIVE_X)][level];
+ egl::Image *negX = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_NEGATIVE_X)][level];
+ egl::Image *posY = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_POSITIVE_Y)][level];
+ egl::Image *negY = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y)][level];
+ egl::Image *posZ = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_POSITIVE_Z)][level];
+ egl::Image *negZ = image[CubeFaceIndex(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)][level];
+
+ if(!posX || !negX || !posY || !negY || !posZ || !negZ)
+ {
+ return;
+ }
+
+ if(posX->getBorder() == 0) // Non-seamless cube map.
+ {
+ return;
+ }
+
+ if(!posX->hasDirtyContents() || !posY->hasDirtyContents() || !posZ->hasDirtyContents() || !negX->hasDirtyContents() || !negY->hasDirtyContents() || !negZ->hasDirtyContents())
+ {
+ return;
+ }
+
+ // Copy top / bottom first.
+ posX->copyCubeEdge(sw::Surface::BOTTOM, negY, sw::Surface::RIGHT);
+ posY->copyCubeEdge(sw::Surface::BOTTOM, posZ, sw::Surface::TOP);
+ posZ->copyCubeEdge(sw::Surface::BOTTOM, negY, sw::Surface::TOP);
+ negX->copyCubeEdge(sw::Surface::BOTTOM, negY, sw::Surface::LEFT);
+ negY->copyCubeEdge(sw::Surface::BOTTOM, negZ, sw::Surface::BOTTOM);
+ negZ->copyCubeEdge(sw::Surface::BOTTOM, negY, sw::Surface::BOTTOM);
+
+ posX->copyCubeEdge(sw::Surface::TOP, posY, sw::Surface::RIGHT);
+ posY->copyCubeEdge(sw::Surface::TOP, negZ, sw::Surface::TOP);
+ posZ->copyCubeEdge(sw::Surface::TOP, posY, sw::Surface::BOTTOM);
+ negX->copyCubeEdge(sw::Surface::TOP, posY, sw::Surface::LEFT);
+ negY->copyCubeEdge(sw::Surface::TOP, posZ, sw::Surface::BOTTOM);
+ negZ->copyCubeEdge(sw::Surface::TOP, posY, sw::Surface::TOP);
+
+ // Copy left / right after top and bottom are done.
+ // The corner colors will be computed assuming top / bottom are already set.
+ posX->copyCubeEdge(sw::Surface::RIGHT, negZ, sw::Surface::LEFT);
+ posY->copyCubeEdge(sw::Surface::RIGHT, posX, sw::Surface::TOP);
+ posZ->copyCubeEdge(sw::Surface::RIGHT, posX, sw::Surface::LEFT);
+ negX->copyCubeEdge(sw::Surface::RIGHT, posZ, sw::Surface::LEFT);
+ negY->copyCubeEdge(sw::Surface::RIGHT, posX, sw::Surface::BOTTOM);
+ negZ->copyCubeEdge(sw::Surface::RIGHT, negX, sw::Surface::LEFT);
+
+ posX->copyCubeEdge(sw::Surface::LEFT, posZ, sw::Surface::RIGHT);
+ posY->copyCubeEdge(sw::Surface::LEFT, negX, sw::Surface::TOP);
+ posZ->copyCubeEdge(sw::Surface::LEFT, negX, sw::Surface::RIGHT);
+ negX->copyCubeEdge(sw::Surface::LEFT, negZ, sw::Surface::RIGHT);
+ negY->copyCubeEdge(sw::Surface::LEFT, negX, sw::Surface::BOTTOM);
+ negZ->copyCubeEdge(sw::Surface::LEFT, posX, sw::Surface::RIGHT);
+
+ posX->markContentsClean();
+ posY->markContentsClean();
+ posZ->markContentsClean();
+ negX->markContentsClean();
+ negY->markContentsClean();
+ negZ->markContentsClean();
+}
+
bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
{
return IsCompressed(getFormat(target, level), egl::getClientVersion());
@@ -1260,7 +1218,7 @@
UNREACHABLE(0); // Cube maps cannot have an EGL surface bound as an image
}
-void TextureCubeMap::setImage(egl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
int face = CubeFaceIndex(target);
@@ -1269,19 +1227,20 @@
image[face][level]->release();
}
- image[face][level] = egl::Image::create(this, width, height, format, type);
+ int border = (egl::getClientVersion() >= 3) ? 1 : 0;
+ image[face][level] = egl::Image::create(this, width, height, 1, border, internalformat);
if(!image[face][level])
{
return error(GL_OUT_OF_MEMORY);
}
- Texture::setImage(context, format, type, unpackInfo, pixels, image[face][level]);
+ Texture::setImage(format, type, unpackParameters, pixels, image[face][level]);
}
-void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
- egl::Image *renderTarget = source->getRenderTarget(0);
+ egl::Image *renderTarget = source->getRenderTarget();
if(!renderTarget)
{
@@ -1296,8 +1255,8 @@
image[face][level]->release();
}
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
- image[face][level] = egl::Image::create(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);
+ int border = (egl::getClientVersion() >= 3) ? 1 : 0;
+ image[face][level] = egl::Image::create(this, width, height, 1, border, internalformat);
if(!image[face][level])
{
@@ -1306,18 +1265,10 @@
if(width != 0 && height != 0)
{
- Renderbuffer* renderbuffer = source->getReadColorbuffer();
-
- if(!renderbuffer)
- {
- ERR("Failed to retrieve the source colorbuffer.");
- return;
- }
-
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
- sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
+ sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
- copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[face][level]);
+ copy(renderTarget, sourceRect, 0, 0, 0, image[face][level]);
}
renderTarget->release();
@@ -1333,7 +1284,7 @@
return image[CubeFaceIndex(face)][level];
}
-void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
int face = CubeFaceIndex(target);
@@ -1349,49 +1300,45 @@
return error(GL_INVALID_VALUE);
}
- egl::Image *renderTarget = source->getRenderTarget(0);
-
- if(!renderTarget)
+ if(width > 0 && height > 0)
{
- ERR("Failed to retrieve the render target.");
- return error(GL_OUT_OF_MEMORY);
+ egl::Image *renderTarget = source->getRenderTarget();
+
+ if(!renderTarget)
+ {
+ ERR("Failed to retrieve the render target.");
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
+ sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
+
+ copy(renderTarget, sourceRect, xoffset, yoffset, zoffset, image[face][level]);
+
+ renderTarget->release();
}
-
- Renderbuffer* renderbuffer = source->getReadColorbuffer();
-
- if(!renderbuffer)
- {
- ERR("Failed to retrieve the source colorbuffer.");
- return;
- }
-
- sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
- sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
-
- copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, zoffset, image[face][level]);
-
- renderTarget->release();
}
void TextureCubeMap::generateMipmaps()
{
- if(!isCubeComplete())
- {
- return error(GL_INVALID_OPERATION);
- }
+ ASSERT(isCubeComplete());
- unsigned int q = log2(image[0][0]->getWidth());
+ int p = log2(image[0][mBaseLevel]->getWidth()) + mBaseLevel;
+ int q = std::min(p, mMaxLevel);
- for(unsigned int f = 0; f < 6; f++)
+ for(int f = 0; f < 6; f++)
{
- for(unsigned int i = 1; i <= q; i++)
+ ASSERT(image[f][mBaseLevel]);
+
+ for(int i = mBaseLevel + 1; i <= q; i++)
{
if(image[f][i])
{
image[f][i]->release();
}
- image[f][i] = egl::Image::create(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());
+ int border = (egl::getClientVersion() >= 3) ? 1 : 0;
+ image[f][i] = egl::Image::create(this, std::max(image[f][mBaseLevel]->getWidth() >> i, 1), std::max(image[f][mBaseLevel]->getHeight() >> i, 1), 1, border, image[f][mBaseLevel]->getFormat());
if(!image[f][i])
{
@@ -1403,7 +1350,7 @@
}
}
-Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level, GLint layer)
+Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level)
{
if(!IsCubemapTextureTarget(target))
{
@@ -1554,52 +1501,40 @@
return image[level] ? image[level]->getDepth() : 0;
}
-GLenum Texture3D::getFormat(GLenum target, GLint level) const
+GLint Texture3D::getFormat(GLenum target, GLint level) const
{
ASSERT(target == getTarget());
return image[level] ? image[level]->getFormat() : GL_NONE;
}
-GLenum Texture3D::getType(GLenum target, GLint level) const
-{
- ASSERT(target == getTarget());
- return image[level] ? image[level]->getType() : GL_NONE;
-}
-
-sw::Format Texture3D::getInternalFormat(GLenum target, GLint level) const
-{
- ASSERT(target == getTarget());
- return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
-}
-
-int Texture3D::getLevelCount() const
+int Texture3D::getTopLevel() const
{
ASSERT(isSamplerComplete());
- int levels = 0;
+ int level = mBaseLevel;
- while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
+ while(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[level])
{
- levels++;
+ level++;
}
- return levels;
+ return level - 1;
}
-void Texture3D::setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
if(image[level])
{
image[level]->release();
}
- image[level] = egl::Image::create(this, width, height, depth, format, type);
+ image[level] = egl::Image::create(this, width, height, depth, 0, internalformat);
if(!image[level])
{
return error(GL_OUT_OF_MEMORY);
}
- Texture::setImage(context, format, type, unpackInfo, pixels, image[level]);
+ Texture::setImage(format, type, unpackParameters, pixels, image[level]);
}
void Texture3D::releaseTexImage()
@@ -1614,8 +1549,7 @@
image[level]->release();
}
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
- image[level] = egl::Image::create(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
+ image[level] = egl::Image::create(this, width, height, depth, 0, format);
if(!image[level])
{
@@ -1625,9 +1559,9 @@
Texture::setCompressedImage(imageSize, pixels, image[level]);
}
-void Texture3D::subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)
+void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels)
{
- Texture::subImage(context, xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels, image[level]);
+ Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackParameters, pixels, image[level]);
}
void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
@@ -1635,9 +1569,9 @@
Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, image[level]);
}
-void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source)
+void Texture3D::copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Renderbuffer *source)
{
- egl::Image *renderTarget = source->getRenderTarget(0);
+ egl::Image *renderTarget = source->getRenderTarget();
if(!renderTarget)
{
@@ -1650,8 +1584,7 @@
image[level]->release();
}
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
- image[level] = egl::Image::create(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);
+ image[level] = egl::Image::create(this, width, height, depth, 0, internalformat);
if(!image[level])
{
@@ -1660,26 +1593,19 @@
if(width != 0 && height != 0 && depth != 0)
{
- Renderbuffer* renderbuffer = source->getReadColorbuffer();
-
- if(!renderbuffer)
- {
- ERR("Failed to retrieve the source colorbuffer.");
- return;
- }
-
sw::SliceRect sourceRect(x, y, x + width, y + height, z);
- sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
- for(GLint sliceZ = 0; sliceZ < depth; ++sliceZ, ++sourceRect.slice)
+ sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
+
+ for(GLint sliceZ = 0; sliceZ < depth; sliceZ++, sourceRect.slice++)
{
- copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, sliceZ, image[level]);
+ copy(renderTarget, sourceRect, 0, 0, sliceZ, image[level]);
}
}
renderTarget->release();
}
-void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
if(!image[level])
{
@@ -1691,28 +1617,23 @@
return error(GL_INVALID_VALUE);
}
- egl::Image *renderTarget = source->getRenderTarget(0);
-
- if(!renderTarget)
+ if(width > 0 && height > 0)
{
- ERR("Failed to retrieve the render target.");
- return error(GL_OUT_OF_MEMORY);
+ egl::Image *renderTarget = source->getRenderTarget();
+
+ if(!renderTarget)
+ {
+ ERR("Failed to retrieve the render target.");
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};
+ sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
+
+ copy(renderTarget, sourceRect, xoffset, yoffset, zoffset, image[level]);
+
+ renderTarget->release();
}
-
- Renderbuffer* renderbuffer = source->getReadColorbuffer();
-
- if(!renderbuffer)
- {
- ERR("Failed to retrieve the source colorbuffer.");
- return;
- }
-
- sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};
- sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
-
- copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
-
- renderTarget->release();
}
void Texture3D::setSharedImage(egl::Image *sharedImage)
@@ -1727,17 +1648,17 @@
image[0] = sharedImage;
}
-// Tests for 3D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+// Tests for 3D texture sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool Texture3D::isSamplerComplete() const
{
- if(!image[0])
+ if(!image[mBaseLevel])
{
return false;
}
- GLsizei width = image[0]->getWidth();
- GLsizei height = image[0]->getHeight();
- GLsizei depth = image[0]->getDepth();
+ GLsizei width = image[mBaseLevel]->getWidth();
+ GLsizei height = image[mBaseLevel]->getHeight();
+ GLsizei depth = image[mBaseLevel]->getDepth();
if(width <= 0 || height <= 0 || depth <= 0)
{
@@ -1755,16 +1676,22 @@
return true;
}
-// Tests for 3D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+// Tests for 3D texture (mipmap) completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
bool Texture3D::isMipmapComplete() const
{
+ if(mBaseLevel > mMaxLevel)
+ {
+ return false;
+ }
+
GLsizei width = image[mBaseLevel]->getWidth();
GLsizei height = image[mBaseLevel]->getHeight();
GLsizei depth = image[mBaseLevel]->getDepth();
bool isTexture2DArray = getTarget() == GL_TEXTURE_2D_ARRAY;
- int q = isTexture2DArray ? std::min(log2(std::max(width, height)), mMaxLevel) :
- std::min(log2(std::max(std::max(width, height), depth)), mMaxLevel);
+ int maxsize = isTexture2DArray ? std::max(width, height) : std::max(std::max(width, height), depth);
+ int p = log2(maxsize) + mBaseLevel;
+ int q = std::min(p, mMaxLevel);
for(int level = mBaseLevel + 1; level <= q; level++)
{
@@ -1773,27 +1700,24 @@
return false;
}
- if(image[level]->getFormat() != image[0]->getFormat())
+ if(image[level]->getFormat() != image[mBaseLevel]->getFormat())
{
return false;
}
- if(image[level]->getType() != image[0]->getType())
+ int i = level - mBaseLevel;
+
+ if(image[level]->getWidth() != std::max(1, width >> i))
{
return false;
}
- if(image[level]->getWidth() != std::max(1, width >> level))
+ if(image[level]->getHeight() != std::max(1, height >> i))
{
return false;
}
- if(image[level]->getHeight() != std::max(1, height >> level))
- {
- return false;
- }
-
- int levelDepth = isTexture2DArray ? depth : std::max(1, depth >> level);
+ int levelDepth = isTexture2DArray ? depth : std::max(1, depth >> i);
if(image[level]->getDepth() != levelDepth)
{
return false;
@@ -1815,21 +1739,20 @@
void Texture3D::generateMipmaps()
{
- if(!image[0])
- {
- return; // FIXME: error?
- }
+ ASSERT(image[mBaseLevel]);
- unsigned int q = log2(std::max(std::max(image[0]->getWidth(), image[0]->getHeight()), image[0]->getDepth()));
+ int maxsize = std::max(std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight()), image[mBaseLevel]->getDepth());
+ int p = log2(maxsize) + mBaseLevel;
+ int q = std::min(p, mMaxLevel);
- for(unsigned int i = 1; i <= q; i++)
+ for(int i = mBaseLevel + 1; i <= q; i++)
{
if(image[i])
{
image[i]->release();
}
- image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), std::max(image[0]->getDepth() >> i, 1), image[0]->getFormat(), image[0]->getType());
+ image[i] = egl::Image::create(this, std::max(image[mBaseLevel]->getWidth() >> i, 1), std::max(image[mBaseLevel]->getHeight() >> i, 1), std::max(image[mBaseLevel]->getDepth() >> i, 1), 0, image[mBaseLevel]->getFormat());
if(!image[i])
{
@@ -1845,7 +1768,7 @@
return image[level];
}
-Renderbuffer *Texture3D::getRenderbuffer(GLenum target, GLint level, GLint layer)
+Renderbuffer *Texture3D::getRenderbuffer(GLenum target, GLint level)
{
if(target != getTarget())
{
@@ -1854,12 +1777,11 @@
if(!mColorbufferProxy)
{
- mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this, level, layer));
+ mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this, level));
}
else
{
mColorbufferProxy->setLevel(level);
- mColorbufferProxy->setLayer(layer);
}
return mColorbufferProxy;
@@ -1911,24 +1833,23 @@
void Texture2DArray::generateMipmaps()
{
- int depth = image[0] ? image[0]->getDepth() : 0;
- if(!depth)
- {
- return; // FIXME: error?
- }
+ ASSERT(image[mBaseLevel]);
- unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+ int depth = image[mBaseLevel]->getDepth();
+ int maxsize = std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight());
+ int p = log2(maxsize) + mBaseLevel;
+ int q = std::min(p, mMaxLevel);
- for(unsigned int i = 1; i <= q; i++)
+ for(int i = mBaseLevel + 1; i <= q; i++)
{
if(image[i])
{
image[i]->release();
}
- GLsizei w = std::max(image[0]->getWidth() >> i, 1);
- GLsizei h = std::max(image[0]->getHeight() >> i, 1);
- image[i] = egl::Image::create(this, w, h, depth, image[0]->getFormat(), image[0]->getType());
+ GLsizei w = std::max(image[mBaseLevel]->getWidth() >> i, 1);
+ GLsizei h = std::max(image[mBaseLevel]->getHeight() >> i, 1);
+ image[i] = egl::Image::create(this, w, h, depth, 0, image[mBaseLevel]->getFormat());
if(!image[i])
{
@@ -1939,7 +1860,7 @@
GLsizei srch = image[i - 1]->getHeight();
for(int z = 0; z < depth; ++z)
{
- sw::SliceRect srcRect(0, 0, srcw, srch, z);
+ sw::SliceRectF srcRect(0.0f, 0.0f, static_cast<float>(srcw), static_cast<float>(srch), z);
sw::SliceRect dstRect(0, 0, w, h, z);
getDevice()->stretchRect(image[i - 1], &srcRect, image[i], &dstRect, Device::ALL_BUFFERS | Device::USE_FILTER);
}
@@ -1974,7 +1895,9 @@
return nullptr;
}
- return egl::Image::create(width, height, format, multiSampleDepth, false);
+ GLenum internalformat = sw2es::ConvertBackBufferFormat(format);
+
+ return egl::Image::create(width, height, internalformat, multiSampleDepth, false);
}
NO_SANITIZE_FUNCTION egl::Image *createDepthStencil(int width, int height, sw::Format format, int multiSampleDepth)
@@ -2010,7 +1933,9 @@
UNREACHABLE(format);
}
- egl::Image *surface = egl::Image::create(width, height, format, multiSampleDepth, lockable);
+ GLenum internalformat = sw2es::ConvertDepthStencilFormat(format);
+
+ egl::Image *surface = egl::Image::create(width, height, internalformat, multiSampleDepth, lockable);
if(!surface)
{
diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h
index 143c51e..54ca5f9 100644
--- a/src/OpenGL/libGLESv2/Texture.h
+++ b/src/OpenGL/libGLESv2/Texture.h
@@ -33,8 +33,6 @@
namespace es2
{
-class Framebuffer;
-
enum
{
IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,
@@ -73,54 +71,52 @@
bool setSwizzleB(GLenum swizzleB);
bool setSwizzleA(GLenum swizzleA);
- GLenum getMinFilter() const;
- GLenum getMagFilter() const;
- GLenum getWrapS() const;
- GLenum getWrapT() const;
- GLenum getWrapR() const;
- GLfloat getMaxAnisotropy() const;
- GLint getBaseLevel() const;
- GLenum getCompareFunc() const;
- GLenum getCompareMode() const;
- GLboolean getImmutableFormat() const;
- GLsizei getImmutableLevels() const;
- GLint getMaxLevel() const;
- GLfloat getMaxLOD() const;
- GLfloat getMinLOD() const;
- GLenum getSwizzleR() const;
- GLenum getSwizzleG() const;
- GLenum getSwizzleB() const;
- GLenum getSwizzleA() const;
+ GLenum getMinFilter() const { return mMinFilter; }
+ GLenum getMagFilter() const { return mMagFilter; }
+ GLenum getWrapS() const { return mWrapS; }
+ GLenum getWrapT() const { return mWrapT; }
+ GLenum getWrapR() const { return mWrapR; }
+ GLfloat getMaxAnisotropy() const { return mMaxAnisotropy; }
+ GLint getBaseLevel() const { return mBaseLevel; }
+ GLenum getCompareFunc() const { return mCompareFunc; }
+ GLenum getCompareMode() const { return mCompareMode; }
+ GLboolean getImmutableFormat() const { return mImmutableFormat; }
+ GLsizei getImmutableLevels() const { return mImmutableLevels; }
+ GLint getMaxLevel() const { return mMaxLevel; }
+ GLfloat getMaxLOD() const { return mMaxLOD; }
+ GLfloat getMinLOD() const { return mMinLOD; }
+ GLenum getSwizzleR() const { return mSwizzleR; }
+ GLenum getSwizzleG() const { return mSwizzleG; }
+ GLenum getSwizzleB() const { return mSwizzleB; }
+ GLenum getSwizzleA() const { return mSwizzleA; }
virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
virtual GLsizei getDepth(GLenum target, GLint level) const;
- virtual GLenum getFormat(GLenum target, GLint level) const = 0;
- virtual GLenum getType(GLenum target, GLint level) const = 0;
- virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
- virtual int getLevelCount() const = 0;
+ virtual GLint getFormat(GLenum target, GLint level) const = 0;
+ virtual int getTopLevel() const = 0;
virtual bool isSamplerComplete() const = 0;
virtual bool isCompressed(GLenum target, GLint level) const = 0;
virtual bool isDepth(GLenum target, GLint level) const = 0;
- virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer) = 0;
+ virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level) = 0;
virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;
egl::Image *createSharedImage(GLenum target, unsigned int level);
virtual bool isShared(GLenum target, unsigned int level) 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;
+ virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) = 0;
protected:
~Texture() override;
- void setImage(egl::Context *context, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image);
- void subImage(egl::Context *context, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image);
+ void setImage(GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image);
+ void subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image);
void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);
void subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image);
- bool copy(egl::Image *source, const sw::SliceRect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest);
+ bool copy(egl::Image *source, const sw::SliceRect &sourceRect, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest);
bool isMipmapFiltered() const;
@@ -159,17 +155,15 @@
GLsizei getWidth(GLenum target, GLint level) const override;
GLsizei getHeight(GLenum target, GLint level) const override;
- GLenum getFormat(GLenum target, GLint level) const override;
- GLenum getType(GLenum target, GLint level) const override;
- sw::Format getInternalFormat(GLenum target, GLint level) const override;
- int getLevelCount() const override;
+ GLint getFormat(GLenum target, GLint level) const override;
+ int getTopLevel() const override;
- void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+ void setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
- void subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+ void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, 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);
- void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) override;
+ void copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
+ void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override;
void setSharedImage(egl::Image *image);
@@ -181,7 +175,7 @@
void generateMipmaps() override;
- Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer) override;
+ Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
egl::Image *getRenderTarget(GLenum target, unsigned int level) override;
bool isShared(GLenum target, unsigned int level) const override;
@@ -205,6 +199,16 @@
unsigned int mProxyRefs;
};
+class Texture2DRect : public Texture2D
+{
+public:
+ explicit Texture2DRect(GLuint name);
+
+ GLenum getTarget() const override;
+
+ Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
+};
+
class TextureCubeMap : public Texture
{
public:
@@ -218,18 +222,16 @@
GLsizei getWidth(GLenum target, GLint level) const override;
GLsizei getHeight(GLenum target, GLint level) const override;
- GLenum getFormat(GLenum target, GLint level) const override;
- GLenum getType(GLenum target, GLint level) const override;
- sw::Format getInternalFormat(GLenum target, GLint level) const override;
- int getLevelCount() const override;
+ GLint getFormat(GLenum target, GLint level) const override;
+ int getTopLevel() const override;
- void setImage(egl::Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+ void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
- void subImage(egl::Context *context, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+ void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, 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);
- void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) override;
+ void copyImage(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
+ void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override;
bool isSamplerComplete() const override;
bool isCompressed(GLenum target, GLint level) const override;
@@ -237,18 +239,20 @@
void releaseTexImage() override;
void generateMipmaps() override;
+ void updateBorders(int level);
- Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer) override;
+ Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
egl::Image *getRenderTarget(GLenum target, unsigned int level) override;
bool isShared(GLenum target, unsigned int level) const override;
egl::Image *getImage(int face, unsigned int level);
+ bool isCubeComplete() const;
+
protected:
~TextureCubeMap() override;
private:
- bool isCubeComplete() const;
bool isMipmapCubeComplete() const;
// face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns nullptr on failure.
@@ -279,17 +283,15 @@
GLsizei getWidth(GLenum target, GLint level) const override;
GLsizei getHeight(GLenum target, GLint level) const override;
GLsizei getDepth(GLenum target, GLint level) const override;
- GLenum getFormat(GLenum target, GLint level) const override;
- GLenum getType(GLenum target, GLint level) const override;
- sw::Format getInternalFormat(GLenum target, GLint level) const override;
- int getLevelCount() const override;
+ GLint getFormat(GLenum target, GLint level) const override;
+ int getTopLevel() const override;
- void setImage(egl::Context *context, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+ void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- void subImage(egl::Context *context, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels);
+ void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- void copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source);
- void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+ void copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Renderbuffer *source);
+ void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
void setSharedImage(egl::Image *image);
@@ -300,7 +302,7 @@
void generateMipmaps() override;
- Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer) override;
+ Renderbuffer *getRenderbuffer(GLenum target, GLint level) override;
egl::Image *getRenderTarget(GLenum target, unsigned int level) override;
bool isShared(GLenum target, unsigned int level) const override;
diff --git a/src/OpenGL/libGLESv2/VertexArray.cpp b/src/OpenGL/libGLESv2/VertexArray.cpp
index d52e7ca..64ae221 100644
--- a/src/OpenGL/libGLESv2/VertexArray.cpp
+++ b/src/OpenGL/libGLESv2/VertexArray.cpp
@@ -65,13 +65,14 @@
}
void VertexArray::setAttributeState(unsigned int attributeIndex, Buffer *boundBuffer, GLint size, GLenum type,
- bool normalized, GLsizei stride, const void *pointer)
+ bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
{
ASSERT(attributeIndex < MAX_VERTEX_ATTRIBS);
mVertexAttributes[attributeIndex].mBoundBuffer = boundBuffer;
mVertexAttributes[attributeIndex].mSize = size;
mVertexAttributes[attributeIndex].mType = type;
mVertexAttributes[attributeIndex].mNormalized = normalized;
+ mVertexAttributes[attributeIndex].mPureInteger = pureInteger;
mVertexAttributes[attributeIndex].mStride = stride;
mVertexAttributes[attributeIndex].mPointer = pointer;
}
diff --git a/src/OpenGL/libGLESv2/VertexArray.h b/src/OpenGL/libGLESv2/VertexArray.h
index 363cf53..bb0f480 100644
--- a/src/OpenGL/libGLESv2/VertexArray.h
+++ b/src/OpenGL/libGLESv2/VertexArray.h
@@ -38,7 +38,7 @@
void setVertexAttribDivisor(GLuint index, GLuint divisor);
void enableAttribute(unsigned int attributeIndex, bool enabledState);
void setAttributeState(unsigned int attributeIndex, Buffer *boundBuffer, GLint size, GLenum type,
- bool normalized, GLsizei stride, const void *pointer);
+ bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
Buffer *getElementArrayBuffer() const { return mElementArrayBuffer; }
void setElementArrayBuffer(Buffer *buffer);
diff --git a/src/OpenGL/libGLESv2/entry_points.cpp b/src/OpenGL/libGLESv2/entry_points.cpp
new file mode 100644
index 0000000..e4b35aa
--- /dev/null
+++ b/src/OpenGL/libGLESv2/entry_points.cpp
@@ -0,0 +1,1428 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// entry_points.cpp: GL entry points exports and definition
+
+#include "main.h"
+
+#include "libEGL/main.h"
+
+namespace es2
+{
+void ActiveTexture(GLenum texture);
+void AttachShader(GLuint program, GLuint shader);
+void BeginQueryEXT(GLenum target, GLuint name);
+void BindAttribLocation(GLuint program, GLuint index, const GLchar* name);
+void BindBuffer(GLenum target, GLuint buffer);
+void BindFramebuffer(GLenum target, GLuint framebuffer);
+void BindRenderbuffer(GLenum target, GLuint renderbuffer);
+void BindTexture(GLenum target, GLuint texture);
+void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void BlendEquation(GLenum mode);
+void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+void BlendFunc(GLenum sfactor, GLenum dfactor);
+void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+GLenum CheckFramebufferStatus(GLenum target);
+void Clear(GLbitfield mask);
+void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void ClearDepthf(GLclampf depth);
+void ClearStencil(GLint s);
+void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+void CompileShader(GLuint shader);
+void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+ GLint border, GLsizei imageSize, const GLvoid* data);
+void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const GLvoid* data);
+void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLuint CreateProgram(void);
+GLuint CreateShader(GLenum type);
+void CullFace(GLenum mode);
+void DeleteBuffers(GLsizei n, const GLuint* buffers);
+void DeleteFencesNV(GLsizei n, const GLuint* fences);
+void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
+void DeleteProgram(GLuint program);
+void DeleteQueriesEXT(GLsizei n, const GLuint *ids);
+void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
+void DeleteShader(GLuint shader);
+void DeleteTextures(GLsizei n, const GLuint* textures);
+void DepthFunc(GLenum func);
+void DepthMask(GLboolean flag);
+void DepthRangef(GLclampf zNear, GLclampf zFar);
+void DetachShader(GLuint program, GLuint shader);
+void Disable(GLenum cap);
+void DisableVertexAttribArray(GLuint index);
+void DrawArrays(GLenum mode, GLint first, GLsizei count);
+void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount);
+void VertexAttribDivisorEXT(GLuint index, GLuint divisor);
+void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount);
+void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+void Enable(GLenum cap);
+void EnableVertexAttribArray(GLuint index);
+void EndQueryEXT(GLenum target);
+void FinishFenceNV(GLuint fence);
+void Finish(void);
+void Flush(void);
+void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void FrontFace(GLenum mode);
+void GenBuffers(GLsizei n, GLuint* buffers);
+void GenerateMipmap(GLenum target);
+void GenFencesNV(GLsizei n, GLuint* fences);
+void GenFramebuffers(GLsizei n, GLuint* framebuffers);
+void GenQueriesEXT(GLsizei n, GLuint* ids);
+void GenRenderbuffers(GLsizei n, GLuint* renderbuffers);
+void GenTextures(GLsizei n, GLuint* textures);
+void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+int GetAttribLocation(GLuint program, const GLchar* name);
+void GetBooleanv(GLenum pname, GLboolean* params);
+void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+GLenum GetError(void);
+void GetFenceivNV(GLuint fence, GLenum pname, GLint *params);
+void GetFloatv(GLenum pname, GLfloat* params);
+void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+GLenum GetGraphicsResetStatusEXT(void);
+void GetIntegerv(GLenum pname, GLint* params);
+void GetProgramiv(GLuint program, GLenum pname, GLint* params);
+void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+void GetQueryivEXT(GLenum target, GLenum pname, GLint *params);
+void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params);
+void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
+void GetShaderiv(GLuint shader, GLenum pname, GLint* params);
+void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+const GLubyte* GetString(GLenum name);
+void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
+void GetUniformfv(GLuint program, GLint location, GLfloat* params);
+void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params);
+void GetUniformiv(GLuint program, GLint location, GLint* params);
+int GetUniformLocation(GLuint program, const GLchar* name);
+void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
+void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
+void Hint(GLenum target, GLenum mode);
+GLboolean IsBuffer(GLuint buffer);
+GLboolean IsEnabled(GLenum cap);
+GLboolean IsFenceNV(GLuint fence);
+GLboolean IsFramebuffer(GLuint framebuffer);
+GLboolean IsProgram(GLuint program);
+GLboolean IsQueryEXT(GLuint name);
+GLboolean IsRenderbuffer(GLuint renderbuffer);
+GLboolean IsShader(GLuint shader);
+GLboolean IsTexture(GLuint texture);
+void LineWidth(GLfloat width);
+void LinkProgram(GLuint program);
+void PixelStorei(GLenum pname, GLint param);
+void PolygonOffset(GLfloat factor, GLfloat units);
+void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+void ReleaseShaderCompiler(void);
+void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+void SampleCoverage(GLclampf value, GLboolean invert);
+void SetFenceNV(GLuint fence, GLenum condition);
+void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length);
+void StencilFunc(GLenum func, GLint ref, GLuint mask);
+void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+void StencilMask(GLuint mask);
+void StencilMaskSeparate(GLenum face, GLuint mask);
+void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+GLboolean TestFenceNV(GLuint fence);
+void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+void TexParameterf(GLenum target, GLenum pname, GLfloat param);
+void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+void TexParameteri(GLenum target, GLenum pname, GLint param);
+void TexParameteriv(GLenum target, GLenum pname, const GLint* params);
+void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid* pixels);
+void Uniform1f(GLint location, GLfloat x);
+void Uniform1fv(GLint location, GLsizei count, const GLfloat* v);
+void Uniform1i(GLint location, GLint x);
+void Uniform1iv(GLint location, GLsizei count, const GLint* v);
+void Uniform2f(GLint location, GLfloat x, GLfloat y);
+void Uniform2fv(GLint location, GLsizei count, const GLfloat* v);
+void Uniform2i(GLint location, GLint x, GLint y);
+void Uniform2iv(GLint location, GLsizei count, const GLint* v);
+void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
+void Uniform3fv(GLint location, GLsizei count, const GLfloat* v);
+void Uniform3i(GLint location, GLint x, GLint y, GLint z);
+void Uniform3iv(GLint location, GLsizei count, const GLint* v);
+void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void Uniform4fv(GLint location, GLsizei count, const GLfloat* v);
+void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
+void Uniform4iv(GLint location, GLsizei count, const GLint* v);
+void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void UseProgram(GLuint program);
+void ValidateProgram(GLuint program);
+void VertexAttrib1f(GLuint index, GLfloat x);
+void VertexAttrib1fv(GLuint index, const GLfloat* values);
+void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
+void VertexAttrib2fv(GLuint index, const GLfloat* values);
+void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+void VertexAttrib3fv(GLuint index, const GLfloat* values);
+void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void VertexAttrib4fv(GLuint index, const GLfloat* values);
+GL_APICALL void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+GL_APICALL void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+GL_APICALL void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+GL_APICALL void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GL_APICALL void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+GL_APICALL void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+GL_APICALL GLboolean IsRenderbufferOES(GLuint renderbuffer);
+GL_APICALL void BindRenderbufferOES(GLenum target, GLuint renderbuffer);
+GL_APICALL void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);
+GL_APICALL void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);
+GL_APICALL void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);
+GL_APICALL GLboolean IsFramebufferOES(GLuint framebuffer);
+GL_APICALL void BindFramebufferOES(GLenum target, GLuint framebuffer);
+GL_APICALL void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);
+GL_APICALL void GenFramebuffersOES(GLsizei n, GLuint* framebuffers);
+GL_APICALL GLenum CheckFramebufferStatusOES(GLenum target);
+GL_APICALL void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+GL_APICALL void GenerateMipmapOES(GLenum target);
+GL_APICALL void DrawBuffersEXT(GLsizei n, const GLenum *bufs);
+}
+
+extern "C"
+{
+GL_APICALL void GL_APIENTRY glActiveTexture(GLenum texture)
+{
+ return es2::ActiveTexture(texture);
+}
+
+GL_APICALL void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
+{
+ return es2::AttachShader(program, shader);
+}
+
+GL_APICALL void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
+{
+ return es2::BeginQueryEXT(target, name);
+}
+
+GL_APICALL void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+ return es2::BindAttribLocation(program, index, name);
+}
+
+GL_APICALL void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
+{
+ return es2::BindBuffer(target, buffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ return es2::BindFramebuffer(target, framebuffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+ return es2::BindFramebuffer(target, framebuffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ return es2::BindRenderbuffer(target, renderbuffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+ return es2::BindRenderbuffer(target, renderbuffer);
+}
+
+GL_APICALL void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+ return es2::BindTexture(target, texture);
+}
+
+GL_APICALL void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ return es2::BlendColor(red, green, blue, alpha);
+}
+
+GL_APICALL void GL_APIENTRY glBlendEquation(GLenum mode)
+{
+ return es2::BlendEquation(mode);
+}
+
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ return es2::BlendEquationSeparate(modeRGB, modeAlpha);
+}
+
+GL_APICALL void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ return es2::BlendFunc(sfactor, dfactor);
+}
+
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ return es2::BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+GL_APICALL void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ return es2::BufferData(target, size, data, usage);
+}
+
+GL_APICALL void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+ return es2::BufferSubData(target, offset, size, data);
+}
+
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
+{
+ return es2::CheckFramebufferStatus(target);
+}
+
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)
+{
+ return es2::CheckFramebufferStatus(target);
+}
+
+GL_APICALL void GL_APIENTRY glClear(GLbitfield mask)
+{
+ return es2::Clear(mask);
+}
+
+GL_APICALL void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ return es2::ClearColor(red, green, blue, alpha);
+}
+
+GL_APICALL void GL_APIENTRY glClearDepthf(GLclampf depth)
+{
+ return es2::ClearDepthf(depth);
+}
+
+GL_APICALL void GL_APIENTRY glClearStencil(GLint s)
+{
+ return es2::ClearStencil(s);
+}
+
+GL_APICALL void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ return es2::ColorMask(red, green, blue, alpha);
+}
+
+GL_APICALL void GL_APIENTRY glCompileShader(GLuint shader)
+{
+ return es2::CompileShader(shader);
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+ GLint border, GLsizei imageSize, const GLvoid* data)
+{
+ return es2::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+ return es2::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ return es2::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ return es2::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+GL_APICALL GLuint GL_APIENTRY glCreateProgram(void)
+{
+ return es2::CreateProgram();
+}
+
+GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type)
+{
+ return es2::CreateShader(type);
+}
+
+GL_APICALL void GL_APIENTRY glCullFace(GLenum mode)
+{
+ return es2::CullFace(mode);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+ return es2::DeleteBuffers(n, buffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+ return es2::DeleteFencesNV(n, fences);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+ return es2::DeleteFramebuffers(n, framebuffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
+{
+ return es2::DeleteFramebuffers(n, framebuffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program)
+{
+ return es2::DeleteProgram(program);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+ return es2::DeleteQueriesEXT(n, ids);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+ return es2::DeleteRenderbuffers(n, renderbuffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
+{
+ return es2::DeleteRenderbuffers(n, renderbuffers);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader)
+{
+ return es2::DeleteShader(shader);
+}
+
+GL_APICALL void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
+{
+ return es2::DeleteTextures(n, textures);
+}
+
+GL_APICALL void GL_APIENTRY glDepthFunc(GLenum func)
+{
+ return es2::DepthFunc(func);
+}
+
+GL_APICALL void GL_APIENTRY glDepthMask(GLboolean flag)
+{
+ return es2::DepthMask(flag);
+}
+
+GL_APICALL void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+ return es2::DepthRangef(zNear, zFar);
+}
+
+GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
+{
+ return es2::DetachShader(program, shader);
+}
+
+GL_APICALL void GL_APIENTRY glDisable(GLenum cap)
+{
+ return es2::Disable(cap);
+}
+
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
+{
+ return es2::DisableVertexAttribArray(index);
+}
+
+GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ return es2::DrawArrays(mode, first, count);
+}
+
+GL_APICALL void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+ return es2::DrawElements(mode, count, type, indices);
+}
+
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+ return es2::DrawArraysInstancedEXT(mode, first, count, instanceCount);
+}
+
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
+{
+ return es2::DrawElementsInstancedEXT(mode, count, type, indices, instanceCount);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT(GLuint index, GLuint divisor)
+{
+ return es2::VertexAttribDivisorEXT(index, divisor);
+}
+
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+ return es2::DrawArraysInstancedANGLE(mode, first, count, instanceCount);
+}
+
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
+{
+ return es2::DrawElementsInstancedANGLE(mode, count, type, indices, instanceCount);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+ return es2::VertexAttribDivisorANGLE(index, divisor);
+}
+
+GL_APICALL void GL_APIENTRY glEnable(GLenum cap)
+{
+ return es2::Enable(cap);
+}
+
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
+{
+ return es2::EnableVertexAttribArray(index);
+}
+
+GL_APICALL void GL_APIENTRY glEndQueryEXT(GLenum target)
+{
+ return es2::EndQueryEXT(target);
+}
+
+GL_APICALL void GL_APIENTRY glFinishFenceNV(GLuint fence)
+{
+ return es2::FinishFenceNV(fence);
+}
+
+GL_APICALL void GL_APIENTRY glFinish(void)
+{
+ return es2::Finish();
+}
+
+GL_APICALL void GL_APIENTRY glFlush(void)
+{
+ return es2::Flush();
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ return es2::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ return es2::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ return es2::FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ return es2::FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+GL_APICALL void GL_APIENTRY glFrontFace(GLenum mode)
+{
+ return es2::FrontFace(mode);
+}
+
+GL_APICALL void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
+{
+ return es2::GenBuffers(n, buffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenerateMipmap(GLenum target)
+{
+ return es2::GenerateMipmap(target);
+}
+
+GL_APICALL void GL_APIENTRY glGenerateMipmapOES(GLenum target)
+{
+ return es2::GenerateMipmap(target);
+}
+
+GL_APICALL void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
+{
+ return es2::GenFencesNV(n, fences);
+}
+
+GL_APICALL void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+ return es2::GenFramebuffers(n, framebuffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)
+{
+ return es2::GenFramebuffers(n, framebuffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
+{
+ return es2::GenQueriesEXT(n, ids);
+}
+
+GL_APICALL void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+ return es2::GenRenderbuffers(n, renderbuffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
+{
+ return es2::GenRenderbuffers(n, renderbuffers);
+}
+
+GL_APICALL void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
+{
+ return es2::GenTextures(n, textures);
+}
+
+GL_APICALL void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+ return es2::GetActiveAttrib(program, index, bufsize, length, size, type, name);
+}
+
+GL_APICALL void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ return es2::GetActiveUniform(program, index, bufsize, length, size, type, name);
+}
+
+GL_APICALL void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+ return es2::GetAttachedShaders(program, maxcount, count, shaders);
+}
+
+GL_APICALL int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
+{
+ return es2::GetAttribLocation(program, name);
+}
+
+GL_APICALL void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
+{
+ return es2::GetBooleanv(pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ return es2::GetBufferParameteriv(target, pname, params);
+}
+
+GL_APICALL GLenum GL_APIENTRY glGetError(void)
+{
+ return es2::GetError();
+}
+
+GL_APICALL void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+ return es2::GetFenceivNV(fence, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
+{
+ return es2::GetFloatv(pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ return es2::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ return es2::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
+
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
+{
+ return es2::GetGraphicsResetStatusEXT();
+}
+
+GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
+{
+ return es2::GetIntegerv(pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+ return es2::GetProgramiv(program, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ return es2::GetProgramInfoLog(program, bufsize, length, infolog);
+}
+
+GL_APICALL void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ return es2::GetQueryivEXT(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
+{
+ return es2::GetQueryObjectuivEXT(name, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ return es2::GetRenderbufferParameteriv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
+{
+ return es2::GetRenderbufferParameteriv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+ return es2::GetShaderiv(shader, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ return es2::GetShaderInfoLog(shader, bufsize, length, infolog);
+}
+
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ return es2::GetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+}
+
+GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+ return es2::GetShaderSource(shader, bufsize, length, source);
+}
+
+GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name)
+{
+ return es2::GetString(name);
+}
+
+GL_APICALL void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+ return es2::GetTexParameterfv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ return es2::GetTexParameteriv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
+{
+ return es2::GetnUniformfvEXT(program, location, bufSize, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+ return es2::GetUniformfv(program, location, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
+{
+ return es2::GetnUniformivEXT(program, location, bufSize, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+ return es2::GetUniformiv(program, location, params);
+}
+
+GL_APICALL int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
+{
+ return es2::GetUniformLocation(program, name);
+}
+
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+ return es2::GetVertexAttribfv(index, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+ return es2::GetVertexAttribiv(index, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+ return es2::GetVertexAttribPointerv(index, pname, pointer);
+}
+
+GL_APICALL void GL_APIENTRY glHint(GLenum target, GLenum mode)
+{
+ return es2::Hint(target, mode);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
+{
+ return es2::IsBuffer(buffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
+{
+ return es2::IsEnabled(cap);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
+{
+ return es2::IsFenceNV(fence);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
+{
+ return es2::IsFramebuffer(framebuffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)
+{
+ return es2::IsFramebuffer(framebuffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsProgram(GLuint program)
+{
+ return es2::IsProgram(program);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT(GLuint name)
+{
+ return es2::IsQueryEXT(name);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
+{
+ return es2::IsRenderbuffer(renderbuffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)
+{
+ return es2::IsRenderbuffer(renderbuffer);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsShader(GLuint shader)
+{
+ return es2::IsShader(shader);
+}
+
+GL_APICALL GLboolean GL_APIENTRY glIsTexture(GLuint texture)
+{
+ return es2::IsTexture(texture);
+}
+
+GL_APICALL void GL_APIENTRY glLineWidth(GLfloat width)
+{
+ return es2::LineWidth(width);
+}
+
+GL_APICALL void GL_APIENTRY glLinkProgram(GLuint program)
+{
+ return es2::LinkProgram(program);
+}
+
+GL_APICALL void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+ return es2::PixelStorei(pname, param);
+}
+
+GL_APICALL void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
+{
+ return es2::PolygonOffset(factor, units);
+}
+
+GL_APICALL void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
+{
+ return es2::ReadnPixelsEXT(x, y, width, height, format, type, bufSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+ return es2::ReadPixels(x, y, width, height, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler(void)
+{
+ return es2::ReleaseShaderCompiler();
+}
+
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ return es2::RenderbufferStorageMultisample(target, samples, internalformat, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ return es2::RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ return es2::RenderbufferStorage(target, internalformat, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ return es2::RenderbufferStorage(target, internalformat, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
+{
+ return es2::SampleCoverage(value, invert);
+}
+
+GL_APICALL void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
+{
+ return es2::SetFenceNV(fence, condition);
+}
+
+GL_APICALL void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ return es2::Scissor(x, y, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+ return es2::ShaderBinary(n, shaders, binaryformat, binary, length);
+}
+
+GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
+{
+ return es2::ShaderSource(shader, count, string, length);
+}
+
+GL_APICALL void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ return es2::StencilFunc(func, ref, mask);
+}
+
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ return es2::StencilFuncSeparate(face, func, ref, mask);
+}
+
+GL_APICALL void GL_APIENTRY glStencilMask(GLuint mask)
+{
+ return es2::StencilMask(mask);
+}
+
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+ return es2::StencilMaskSeparate(face, mask);
+}
+
+GL_APICALL void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ return es2::StencilOp(fail, zfail, zpass);
+}
+
+GL_APICALL void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ return es2::StencilOpSeparate(face, fail, zfail, zpass);
+}
+
+GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
+{
+ return es2::TestFenceNV(fence);
+}
+
+GL_APICALL void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ return es2::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ return es2::TexParameterf(target, pname, param);
+}
+
+GL_APICALL void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+ return es2::TexParameterfv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ return es2::TexParameteri(target, pname, param);
+}
+
+GL_APICALL void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+ return es2::TexParameteriv(target, pname, params);
+}
+
+GL_APICALL void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid* pixels)
+{
+ return es2::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
+{
+ return es2::Uniform1f(location, x);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ return es2::Uniform1fv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1i(GLint location, GLint x)
+{
+ return es2::Uniform1i(location, x);
+}
+
+GL_APICALL void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+ return es2::Uniform1iv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ return es2::Uniform2f(location, x, y);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ return es2::Uniform2fv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
+{
+ return es2::Uniform2i(location, x, y);
+}
+
+GL_APICALL void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+ return es2::Uniform2iv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ return es2::Uniform3f(location, x, y, z);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ return es2::Uniform3fv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+ return es2::Uniform3i(location, x, y, z);
+}
+
+GL_APICALL void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+ return es2::Uniform3iv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ return es2::Uniform4f(location, x, y, z, w);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ return es2::Uniform4fv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ return es2::Uniform4i(location, x, y, z, w);
+}
+
+GL_APICALL void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+ return es2::Uniform4iv(location, count, v);
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ return es2::UniformMatrix2fv(location, count, transpose, value);
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ return es2::UniformMatrix3fv(location, count, transpose, value);
+}
+
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ return es2::UniformMatrix4fv(location, count, transpose, value);
+}
+
+GL_APICALL void GL_APIENTRY glUseProgram(GLuint program)
+{
+ return es2::UseProgram(program);
+}
+
+GL_APICALL void GL_APIENTRY glValidateProgram(GLuint program)
+{
+ return es2::ValidateProgram(program);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
+{
+ return es2::VertexAttrib1f(index, x);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
+{
+ return es2::VertexAttrib1fv(index, values);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+ return es2::VertexAttrib2f(index, x, y);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
+{
+ return es2::VertexAttrib2fv(index, values);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+ return es2::VertexAttrib3f(index, x, y, z);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
+{
+ return es2::VertexAttrib3fv(index, values);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ return es2::VertexAttrib4f(index, x, y, z, w);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
+{
+ return es2::VertexAttrib4fv(index, values);
+}
+
+GL_APICALL void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+ return es2::VertexAttribPointer(index, size, type, normalized, stride, ptr);
+}
+
+GL_APICALL void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ return es2::Viewport(x, y, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glBlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+{
+ return es2::BlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ return es2::BlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+GL_APICALL void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ return es2::TexImage3DOES(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
+{
+ return es2::TexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+}
+
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ return es2::CopyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
+{
+ return es2::CompressedTexImage3DOES(target, level,internalformat, width, height, depth, border, imageSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
+{
+ return es2::CompressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+}
+
+GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+ return es2::FramebufferTexture3DOES(target, attachment, textarget, texture, level, zoffset);
+}
+
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+ return es2::EGLImageTargetTexture2DOES(target, image);
+}
+
+GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+ return es2::EGLImageTargetRenderbufferStorageOES(target, image);
+}
+
+GL_APICALL void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+ return es2::DrawBuffersEXT(n, bufs);
+}
+
+void GL_APIENTRY Register(const char *licenseKey)
+{
+ // Nothing to do, SwiftShader is open-source
+}
+}
+
+egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, int clientVersion, const egl::Config *config);
+extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname);
+egl::Image *createBackBuffer(int width, int height, sw::Format format, int multiSampleDepth);
+egl::Image *createDepthStencil(int width, int height, sw::Format format, int multiSampleDepth);
+sw::FrameBuffer *createFrameBuffer(void *nativeDisplay, EGLNativeWindowType window, int width, int height);
+
+LibGLESv2exports::LibGLESv2exports()
+{
+ this->glActiveTexture = es2::ActiveTexture;
+ this->glAttachShader = es2::AttachShader;
+ this->glBeginQueryEXT = es2::BeginQueryEXT;
+ this->glBindAttribLocation = es2::BindAttribLocation;
+ this->glBindBuffer = es2::BindBuffer;
+ this->glBindFramebuffer = es2::BindFramebuffer;
+ this->glBindRenderbuffer = es2::BindRenderbuffer;
+ this->glBindTexture = es2::BindTexture;
+ this->glBlendColor = es2::BlendColor;
+ this->glBlendEquation = es2::BlendEquation;
+ this->glBlendEquationSeparate = es2::BlendEquationSeparate;
+ this->glBlendFunc = es2::BlendFunc;
+ this->glBlendFuncSeparate = es2::BlendFuncSeparate;
+ this->glBufferData = es2::BufferData;
+ this->glBufferSubData = es2::BufferSubData;
+ this->glCheckFramebufferStatus = es2::CheckFramebufferStatus;
+ this->glClear = es2::Clear;
+ this->glClearColor = es2::ClearColor;
+ this->glClearDepthf = es2::ClearDepthf;
+ this->glClearStencil = es2::ClearStencil;
+ this->glColorMask = es2::ColorMask;
+ this->glCompileShader = es2::CompileShader;
+ this->glCompressedTexImage2D = es2::CompressedTexImage2D;
+ this->glCompressedTexSubImage2D = es2::CompressedTexSubImage2D;
+ this->glCopyTexImage2D = es2::CopyTexImage2D;
+ this->glCopyTexSubImage2D = es2::CopyTexSubImage2D;
+ this->glCreateProgram = es2::CreateProgram;
+ this->glCreateShader = es2::CreateShader;
+ this->glCullFace = es2::CullFace;
+ this->glDeleteBuffers = es2::DeleteBuffers;
+ this->glDeleteFencesNV = es2::DeleteFencesNV;
+ this->glDeleteFramebuffers = es2::DeleteFramebuffers;
+ this->glDeleteProgram = es2::DeleteProgram;
+ this->glDeleteQueriesEXT = es2::DeleteQueriesEXT;
+ this->glDeleteRenderbuffers = es2::DeleteRenderbuffers;
+ this->glDeleteShader = es2::DeleteShader;
+ this->glDeleteTextures = es2::DeleteTextures;
+ this->glDepthFunc = es2::DepthFunc;
+ this->glDepthMask = es2::DepthMask;
+ this->glDepthRangef = es2::DepthRangef;
+ this->glDetachShader = es2::DetachShader;
+ this->glDisable = es2::Disable;
+ this->glDisableVertexAttribArray = es2::DisableVertexAttribArray;
+ this->glDrawArrays = es2::DrawArrays;
+ this->glDrawElements = es2::DrawElements;
+ this->glDrawArraysInstancedEXT = es2::DrawArraysInstancedEXT;
+ this->glDrawElementsInstancedEXT = es2::DrawElementsInstancedEXT;
+ this->glVertexAttribDivisorEXT = es2::VertexAttribDivisorEXT;
+ this->glDrawArraysInstancedANGLE = es2::DrawArraysInstancedANGLE;
+ this->glDrawElementsInstancedANGLE = es2::DrawElementsInstancedANGLE;
+ this->glVertexAttribDivisorANGLE = es2::VertexAttribDivisorANGLE;
+ this->glEnable = es2::Enable;
+ this->glEnableVertexAttribArray = es2::EnableVertexAttribArray;
+ this->glEndQueryEXT = es2::EndQueryEXT;
+ this->glFinishFenceNV = es2::FinishFenceNV;
+ this->glFinish = es2::Finish;
+ this->glFlush = es2::Flush;
+ this->glFramebufferRenderbuffer = es2::FramebufferRenderbuffer;
+ this->glFramebufferTexture2D = es2::FramebufferTexture2D;
+ this->glFrontFace = es2::FrontFace;
+ this->glGenBuffers = es2::GenBuffers;
+ this->glGenerateMipmap = es2::GenerateMipmap;
+ this->glGenFencesNV = es2::GenFencesNV;
+ this->glGenFramebuffers = es2::GenFramebuffers;
+ this->glGenQueriesEXT = es2::GenQueriesEXT;
+ this->glGenRenderbuffers = es2::GenRenderbuffers;
+ this->glGenTextures = es2::GenTextures;
+ this->glGetActiveAttrib = es2::GetActiveAttrib;
+ this->glGetActiveUniform = es2::GetActiveUniform;
+ this->glGetAttachedShaders = es2::GetAttachedShaders;
+ this->glGetAttribLocation = es2::GetAttribLocation;
+ this->glGetBooleanv = es2::GetBooleanv;
+ this->glGetBufferParameteriv = es2::GetBufferParameteriv;
+ this->glGetError = es2::GetError;
+ this->glGetFenceivNV = es2::GetFenceivNV;
+ this->glGetFloatv = es2::GetFloatv;
+ this->glGetFramebufferAttachmentParameteriv = es2::GetFramebufferAttachmentParameteriv;
+ this->glGetGraphicsResetStatusEXT = es2::GetGraphicsResetStatusEXT;
+ this->glGetIntegerv = es2::GetIntegerv;
+ this->glGetProgramiv = es2::GetProgramiv;
+ this->glGetProgramInfoLog = es2::GetProgramInfoLog;
+ this->glGetQueryivEXT = es2::GetQueryivEXT;
+ this->glGetQueryObjectuivEXT = es2::GetQueryObjectuivEXT;
+ this->glGetRenderbufferParameteriv = es2::GetRenderbufferParameteriv;
+ this->glGetShaderiv = es2::GetShaderiv;
+ this->glGetShaderInfoLog = es2::GetShaderInfoLog;
+ this->glGetShaderPrecisionFormat = es2::GetShaderPrecisionFormat;
+ this->glGetShaderSource = es2::GetShaderSource;
+ this->glGetString = es2::GetString;
+ this->glGetTexParameterfv = es2::GetTexParameterfv;
+ this->glGetTexParameteriv = es2::GetTexParameteriv;
+ this->glGetnUniformfvEXT = es2::GetnUniformfvEXT;
+ this->glGetUniformfv = es2::GetUniformfv;
+ this->glGetnUniformivEXT = es2::GetnUniformivEXT;
+ this->glGetUniformiv = es2::GetUniformiv;
+ this->glGetUniformLocation = es2::GetUniformLocation;
+ this->glGetVertexAttribfv = es2::GetVertexAttribfv;
+ this->glGetVertexAttribiv = es2::GetVertexAttribiv;
+ this->glGetVertexAttribPointerv = es2::GetVertexAttribPointerv;
+ this->glHint = es2::Hint;
+ this->glIsBuffer = es2::IsBuffer;
+ this->glIsEnabled = es2::IsEnabled;
+ this->glIsFenceNV = es2::IsFenceNV;
+ this->glIsFramebuffer = es2::IsFramebuffer;
+ this->glIsProgram = es2::IsProgram;
+ this->glIsQueryEXT = es2::IsQueryEXT;
+ this->glIsRenderbuffer = es2::IsRenderbuffer;
+ this->glIsShader = es2::IsShader;
+ this->glIsTexture = es2::IsTexture;
+ this->glLineWidth = es2::LineWidth;
+ this->glLinkProgram = es2::LinkProgram;
+ this->glPixelStorei = es2::PixelStorei;
+ this->glPolygonOffset = es2::PolygonOffset;
+ this->glReadnPixelsEXT = es2::ReadnPixelsEXT;
+ this->glReadPixels = es2::ReadPixels;
+ this->glReleaseShaderCompiler = es2::ReleaseShaderCompiler;
+ this->glRenderbufferStorageMultisample = es2::RenderbufferStorageMultisample;
+ this->glRenderbufferStorageMultisampleANGLE = es2::RenderbufferStorageMultisampleANGLE;
+ this->glRenderbufferStorage = es2::RenderbufferStorage;
+ this->glSampleCoverage = es2::SampleCoverage;
+ this->glSetFenceNV = es2::SetFenceNV;
+ this->glScissor = es2::Scissor;
+ this->glShaderBinary = es2::ShaderBinary;
+ this->glShaderSource = es2::ShaderSource;
+ this->glStencilFunc = es2::StencilFunc;
+ this->glStencilFuncSeparate = es2::StencilFuncSeparate;
+ this->glStencilMask = es2::StencilMask;
+ this->glStencilMaskSeparate = es2::StencilMaskSeparate;
+ this->glStencilOp = es2::StencilOp;
+ this->glStencilOpSeparate = es2::StencilOpSeparate;
+ this->glTestFenceNV = es2::TestFenceNV;
+ this->glTexImage2D = es2::TexImage2D;
+ this->glTexParameterf = es2::TexParameterf;
+ this->glTexParameterfv = es2::TexParameterfv;
+ this->glTexParameteri = es2::TexParameteri;
+ this->glTexParameteriv = es2::TexParameteriv;
+ this->glTexSubImage2D = es2::TexSubImage2D;
+ this->glUniform1f = es2::Uniform1f;
+ this->glUniform1fv = es2::Uniform1fv;
+ this->glUniform1i = es2::Uniform1i;
+ this->glUniform1iv = es2::Uniform1iv;
+ this->glUniform2f = es2::Uniform2f;
+ this->glUniform2fv = es2::Uniform2fv;
+ this->glUniform2i = es2::Uniform2i;
+ this->glUniform2iv = es2::Uniform2iv;
+ this->glUniform3f = es2::Uniform3f;
+ this->glUniform3fv = es2::Uniform3fv;
+ this->glUniform3i = es2::Uniform3i;
+ this->glUniform3iv = es2::Uniform3iv;
+ this->glUniform4f = es2::Uniform4f;
+ this->glUniform4fv = es2::Uniform4fv;
+ this->glUniform4i = es2::Uniform4i;
+ this->glUniform4iv = es2::Uniform4iv;
+ this->glUniformMatrix2fv = es2::UniformMatrix2fv;
+ this->glUniformMatrix3fv = es2::UniformMatrix3fv;
+ this->glUniformMatrix4fv = es2::UniformMatrix4fv;
+ this->glUseProgram = es2::UseProgram;
+ this->glValidateProgram = es2::ValidateProgram;
+ this->glVertexAttrib1f = es2::VertexAttrib1f;
+ this->glVertexAttrib1fv = es2::VertexAttrib1fv;
+ this->glVertexAttrib2f = es2::VertexAttrib2f;
+ this->glVertexAttrib2fv = es2::VertexAttrib2fv;
+ this->glVertexAttrib3f = es2::VertexAttrib3f;
+ this->glVertexAttrib3fv = es2::VertexAttrib3fv;
+ this->glVertexAttrib4f = es2::VertexAttrib4f;
+ this->glVertexAttrib4fv = es2::VertexAttrib4fv;
+ this->glVertexAttribPointer = es2::VertexAttribPointer;
+ this->glViewport = es2::Viewport;
+ this->glBlitFramebufferNV = es2::BlitFramebufferNV;
+ this->glBlitFramebufferANGLE = es2::BlitFramebufferANGLE;
+ this->glTexImage3DOES = es2::TexImage3DOES;
+ this->glTexSubImage3DOES = es2::TexSubImage3DOES;
+ this->glCopyTexSubImage3DOES = es2::CopyTexSubImage3DOES;
+ this->glCompressedTexImage3DOES = es2::CompressedTexImage3DOES;
+ this->glCompressedTexSubImage3DOES = es2::CompressedTexSubImage3DOES;
+ this->glFramebufferTexture3DOES = es2::FramebufferTexture3DOES;
+ this->glEGLImageTargetTexture2DOES = es2::EGLImageTargetTexture2DOES;
+ this->glEGLImageTargetRenderbufferStorageOES = es2::EGLImageTargetRenderbufferStorageOES;
+ this->glIsRenderbufferOES = es2::IsRenderbufferOES;
+ this->glBindRenderbufferOES = es2::BindRenderbufferOES;
+ this->glDeleteRenderbuffersOES = es2::DeleteRenderbuffersOES;
+ this->glGenRenderbuffersOES = es2::GenRenderbuffersOES;
+ this->glRenderbufferStorageOES = es2::RenderbufferStorageOES;
+ this->glGetRenderbufferParameterivOES = es2::GetRenderbufferParameterivOES;
+ this->glIsFramebufferOES = es2::IsFramebufferOES;
+ this->glBindFramebufferOES = es2::BindFramebufferOES;
+ this->glDeleteFramebuffersOES = es2::DeleteFramebuffersOES;
+ this->glGenFramebuffersOES = es2::GenFramebuffersOES;
+ this->glCheckFramebufferStatusOES = es2::CheckFramebufferStatusOES;
+ this->glFramebufferRenderbufferOES = es2::FramebufferRenderbufferOES;
+ this->glFramebufferTexture2DOES = es2::FramebufferTexture2DOES;
+ this->glGetFramebufferAttachmentParameterivOES = es2::GetFramebufferAttachmentParameterivOES;
+ this->glGenerateMipmapOES = es2::GenerateMipmapOES;
+ this->glDrawBuffersEXT = es2::DrawBuffersEXT;
+
+ this->es2CreateContext = ::es2CreateContext;
+ this->es2GetProcAddress = ::es2GetProcAddress;
+ this->createBackBuffer = ::createBackBuffer;
+ this->createDepthStencil = ::createDepthStencil;
+ this->createFrameBuffer = ::createFrameBuffer;
+}
+
+extern "C" GL_APICALL LibGLESv2exports *libGLESv2_swiftshader()
+{
+ static LibGLESv2exports libGLESv2;
+ return &libGLESv2;
+}
+
+LibEGL libEGL;
+LibGLES_CM libGLES_CM;
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index f486982..4be0273 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -26,6 +26,7 @@
#include "Texture.h"
#include "Query.h"
#include "TransformFeedback.h"
+#include "VertexArray.h"
#include "common/debug.h"
#include "Common/Version.h"
@@ -33,6 +34,7 @@
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
+#include <algorithm>
#include <limits>
#ifdef __ANDROID__
@@ -52,70 +54,6 @@
return true;
}
-static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
-{
- GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);
- if(validationError != GL_NONE)
- {
- return error(validationError, false);
- }
-
- // [OpenGL ES 2.0.24] table 3.9
- switch(textureFormat)
- {
- case GL_ALPHA:
- if(colorbufferFormat != GL_ALPHA &&
- colorbufferFormat != GL_RGBA &&
- colorbufferFormat != GL_RGBA4 &&
- colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8_OES &&
- colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA16F_EXT &&
- colorbufferFormat != GL_RGBA32F_EXT)
- {
- return error(GL_INVALID_OPERATION, false);
- }
- break;
- case GL_LUMINANCE:
- case GL_RGB:
- if(colorbufferFormat != GL_RGB &&
- colorbufferFormat != GL_RGB565 &&
- colorbufferFormat != GL_RGB8_OES &&
- colorbufferFormat != GL_RGBA &&
- colorbufferFormat != GL_RGBA4 &&
- colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8_OES &&
- colorbufferFormat != GL_RGB16F_EXT &&
- colorbufferFormat != GL_RGB32F_EXT &&
- colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA16F_EXT &&
- colorbufferFormat != GL_RGBA32F_EXT)
- {
- return error(GL_INVALID_OPERATION, false);
- }
- break;
- case GL_LUMINANCE_ALPHA:
- case GL_RGBA:
- if(colorbufferFormat != GL_RGBA &&
- colorbufferFormat != GL_RGBA4 &&
- colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8_OES &&
- colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA16F_EXT &&
- colorbufferFormat != GL_RGBA32F_EXT)
- {
- return error(GL_INVALID_OPERATION, false);
- }
- break;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_STENCIL_OES:
- return error(GL_INVALID_OPERATION, false);
- default:
- return error(GL_INVALID_ENUM, false);
- }
- return true;
-}
-
void ActiveTexture(GLenum texture)
{
TRACE("(GLenum texture = 0x%X)", texture);
@@ -307,7 +245,7 @@
{
TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
- if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+ if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
{
return error(GL_INVALID_ENUM);
}
@@ -316,12 +254,12 @@
if(context)
{
- if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ if(target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
{
context->bindReadFramebuffer(framebuffer);
}
- if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ if(target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
{
context->bindDrawFramebuffer(framebuffer);
}
@@ -369,23 +307,26 @@
switch(target)
{
case GL_TEXTURE_2D:
- context->bindTexture2D(texture);
+ context->bindTexture(TEXTURE_2D, texture);
break;
case GL_TEXTURE_CUBE_MAP:
- context->bindTextureCubeMap(texture);
+ context->bindTexture(TEXTURE_CUBE, texture);
break;
case GL_TEXTURE_EXTERNAL_OES:
- context->bindTextureExternal(texture);
+ context->bindTexture(TEXTURE_EXTERNAL, texture);
break;
case GL_TEXTURE_2D_ARRAY:
if(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
- context->bindTexture2DArray(texture);
+ context->bindTexture(TEXTURE_2D_ARRAY, texture);
break;
- case GL_TEXTURE_3D_OES:
- context->bindTexture3D(texture);
+ case GL_TEXTURE_3D:
+ context->bindTexture(TEXTURE_3D, texture);
+ break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ context->bindTexture(TEXTURE_2D_RECT, texture);
break;
default:
return error(GL_INVALID_ENUM);
@@ -649,6 +590,12 @@
return error(GL_INVALID_OPERATION);
}
+ if(buffer->isMapped())
+ {
+ // It is an invalid operation to update an already mapped buffer
+ return error(GL_INVALID_OPERATION);
+ }
+
if((size_t)size + offset > buffer->size())
{
return error(GL_INVALID_VALUE);
@@ -662,7 +609,7 @@
{
TRACE("(GLenum target = 0x%X)", target);
- if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+ if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
{
return error(GL_INVALID_ENUM, 0);
}
@@ -672,7 +619,7 @@
if(context)
{
es2::Framebuffer *framebuffer = nullptr;
- if(target == GL_READ_FRAMEBUFFER_ANGLE)
+ if(target == GL_READ_FRAMEBUFFER)
{
framebuffer = context->getReadFramebuffer();
}
@@ -792,23 +739,9 @@
return error(GL_INVALID_VALUE);
}
- switch(internalformat)
+ if(!IsCompressed(internalformat, egl::getClientVersion()))
{
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT32_OES:
- case GL_DEPTH_STENCIL_OES:
- case GL_DEPTH24_STENCIL8_OES:
- return error(GL_INVALID_OPERATION);
- default:
- {
- GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
- if(validationError != GL_NONE)
- {
- return error(validationError);
- }
- }
- break;
+ return error(GL_INVALID_ENUM);
}
if(border != 0)
@@ -851,18 +784,25 @@
return error(GL_INVALID_VALUE);
}
break;
+ case GL_TEXTURE_RECTANGLE_ARB: // Rectangle textures cannot be compressed
default:
return error(GL_INVALID_ENUM);
}
- if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
+ if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
{
return error(GL_INVALID_VALUE);
}
- if(target == GL_TEXTURE_2D)
+ GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
+ if(validationError != GL_NO_ERROR)
{
- es2::Texture2D *texture = context->getTexture2D();
+ return error(validationError);
+ }
+
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ es2::Texture2D *texture = context->getTexture2D(target);
if(!texture)
{
@@ -871,7 +811,7 @@
texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
}
- else
+ else if(es2::IsCubemapTextureTarget(target))
{
es2::TextureCubeMap *texture = context->getTextureCubeMap();
@@ -880,19 +820,9 @@
return error(GL_INVALID_OPERATION);
}
- switch(target)
- {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
- break;
- default: UNREACHABLE(target);
- }
+ texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
}
+ else UNREACHABLE(target);
}
}
@@ -919,63 +849,50 @@
return error(GL_INVALID_VALUE);
}
- GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
- if(validationError != GL_NONE)
+ if(imageSize != gl::ComputeCompressedSize(width, height, format))
{
- return error(validationError);
- }
-
- if(width == 0 || height == 0 || !data)
- {
- return;
+ return error(GL_INVALID_VALUE);
}
es2::Context *context = es2::getContext();
if(context)
{
- if(imageSize != egl::ComputeCompressedSize(width, height, format))
- {
- return error(GL_INVALID_VALUE);
- }
-
if(xoffset % 4 != 0 || yoffset % 4 != 0)
{
// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
return error(GL_INVALID_OPERATION);
}
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);
-
- if(target == GL_TEXTURE_2D)
+ GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
+ if(validationError != GL_NO_ERROR)
{
- es2::Texture2D *texture = context->getTexture2D();
+ return error(validationError);
+ }
- GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ es2::Texture2D *texture = context->getTexture2D(target);
- if(validationError == GL_NONE)
- {
- texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, context->getPixels(data));
- }
- else
+ GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
+
+ texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
}
else if(es2::IsCubemapTextureTarget(target))
{
es2::TextureCubeMap *texture = context->getTextureCubeMap();
- GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
-
- if(validationError == GL_NONE)
- {
- texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, context->getPixels(data));
- }
- else
+ GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
+
+ texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
}
else UNREACHABLE(target);
}
@@ -1003,6 +920,12 @@
{
switch(target)
{
+ case GL_TEXTURE_RECTANGLE_ARB:
+ if(level != 0)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ // Fall through
case GL_TEXTURE_2D:
if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
@@ -1047,21 +970,40 @@
GLenum colorbufferFormat = source->getFormat();
- if(!validateColorBufferFormat(internalformat, colorbufferFormat))
+ // Determine the sized internal format.
+ if(gl::IsUnsizedInternalFormat(internalformat))
+ {
+ if(gl::GetBaseInternalFormat(colorbufferFormat) == internalformat)
+ {
+ internalformat = colorbufferFormat;
+ }
+ else if(GetRedSize(colorbufferFormat) == 8)
+ {
+ internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_BYTE);
+ }
+ else
+ {
+ UNIMPLEMENTED();
+
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+
+ if(!ValidateCopyFormats(internalformat, colorbufferFormat))
{
return;
}
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- es2::Texture2D *texture = context->getTexture2D();
+ es2::Texture2D *texture = context->getTexture2D(target);
if(!texture)
{
return error(GL_INVALID_OPERATION);
}
- texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+ texture->copyImage(level, internalformat, x, y, width, height, source);
}
else if(es2::IsCubemapTextureTarget(target))
{
@@ -1072,7 +1014,7 @@
return error(GL_INVALID_OPERATION);
}
- texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
+ texture->copyImage(target, level, internalformat, x, y, width, height, source);
}
else UNREACHABLE(target);
}
@@ -1104,11 +1046,6 @@
return error(GL_INVALID_VALUE);
}
- if(width == 0 || height == 0)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -1129,9 +1066,9 @@
es2::Texture *texture = nullptr;
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- texture = context->getTexture2D();
+ texture = context->getTexture2D(target);
}
else if(es2::IsCubemapTextureTarget(target))
{
@@ -1139,13 +1076,13 @@
}
else UNREACHABLE(target);
- GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);
- if(validationError != GL_NONE)
+ GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE, GL_NONE, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
- texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
+ texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, source);
}
}
@@ -1946,7 +1883,7 @@
TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
"GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
- if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
+ if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) ||
(renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
{
return error(GL_INVALID_ENUM);
@@ -1958,7 +1895,7 @@
{
es2::Framebuffer *framebuffer = nullptr;
GLuint framebufferName = 0;
- if(target == GL_READ_FRAMEBUFFER_ANGLE)
+ if(target == GL_READ_FRAMEBUFFER)
{
framebuffer = context->getReadFramebuffer();
framebufferName = context->getReadFramebufferName();
@@ -2053,7 +1990,7 @@
TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
"GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
- if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+ if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
{
return error(GL_INVALID_ENUM);
}
@@ -2085,6 +2022,12 @@
return error(GL_INVALID_OPERATION);
}
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ if(tex->getTarget() != GL_TEXTURE_RECTANGLE_ARB)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
@@ -2100,7 +2043,7 @@
return error(GL_INVALID_ENUM);
}
- if((level != 0) && (clientVersion < 3))
+ if((level != 0) && ((clientVersion < 3) || (textarget == GL_TEXTURE_RECTANGLE_ARB)))
{
return error(GL_INVALID_VALUE);
}
@@ -2118,7 +2061,7 @@
es2::Framebuffer *framebuffer = nullptr;
GLuint framebufferName = 0;
- if(target == GL_READ_FRAMEBUFFER_ANGLE)
+ if(target == GL_READ_FRAMEBUFFER)
{
framebuffer = context->getReadFramebuffer();
framebufferName = context->getReadFramebufferName();
@@ -2250,7 +2193,15 @@
texture = context->getTexture2D();
break;
case GL_TEXTURE_CUBE_MAP:
- texture = context->getTextureCubeMap();
+ {
+ TextureCubeMap *cube = context->getTextureCubeMap();
+ texture = cube;
+
+ if(!cube->isCubeComplete())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
break;
case GL_TEXTURE_2D_ARRAY:
if(clientVersion < 3)
@@ -2262,14 +2213,17 @@
texture = context->getTexture2DArray();
}
break;
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
texture = context->getTexture3D();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
- if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
+ if(!IsMipmappable(texture->getFormat(target, texture->getBaseLevel()), clientVersion))
{
return error(GL_INVALID_OPERATION);
}
@@ -2740,121 +2694,86 @@
return error(GL_INVALID_ENUM);
}
- GLint clientVersion = context->getClientVersion();
+ GLuint framebufferName = 0;
- es2::Framebuffer *framebuffer = nullptr;
if(target == GL_READ_FRAMEBUFFER)
{
- if(context->getReadFramebufferName() == 0)
- {
- if(clientVersion < 3)
- {
- return error(GL_INVALID_OPERATION);
- }
- else
- {
- switch(attachment)
- {
- case GL_BACK:
- case GL_DEPTH:
- case GL_STENCIL:
- break;
- default:
- return error(GL_INVALID_ENUM);
- }
- }
- }
-
- framebuffer = context->getReadFramebuffer();
+ framebufferName = context->getReadFramebufferName();
}
else
{
- if(context->getDrawFramebufferName() == 0)
- {
- if(clientVersion < 3)
- {
- return error(GL_INVALID_OPERATION);
- }
- else
- {
- switch(attachment)
- {
- case GL_BACK:
- case GL_DEPTH:
- case GL_STENCIL:
- break;
- default:
- return error(GL_INVALID_ENUM);
- }
- }
- }
-
- framebuffer = context->getDrawFramebuffer();
+ framebufferName = context->getDrawFramebufferName();
}
- GLenum attachmentType;
- GLuint attachmentHandle;
- GLint attachmentLayer;
- Renderbuffer* renderbuffer = nullptr;
+ GLint clientVersion = context->getClientVersion();
+
+ if(framebufferName == 0) // Default framebuffer.
+ {
+ if(clientVersion < 3)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+
switch(attachment)
{
case GL_BACK:
- if(clientVersion >= 3)
- {
- attachmentType = framebuffer->getColorbufferType(0);
- attachmentHandle = framebuffer->getColorbufferName(0);
- attachmentLayer = framebuffer->getColorbufferLayer(0);
- renderbuffer = framebuffer->getColorbuffer(0);
- }
- else return error(GL_INVALID_ENUM);
- break;
- case GL_COLOR_ATTACHMENT0:
- case GL_COLOR_ATTACHMENT1:
- case GL_COLOR_ATTACHMENT2:
- case GL_COLOR_ATTACHMENT3:
- case GL_COLOR_ATTACHMENT4:
- case GL_COLOR_ATTACHMENT5:
- case GL_COLOR_ATTACHMENT6:
- case GL_COLOR_ATTACHMENT7:
- case GL_COLOR_ATTACHMENT8:
- case GL_COLOR_ATTACHMENT9:
- case GL_COLOR_ATTACHMENT10:
- case GL_COLOR_ATTACHMENT11:
- case GL_COLOR_ATTACHMENT12:
- case GL_COLOR_ATTACHMENT13:
- case GL_COLOR_ATTACHMENT14:
- case GL_COLOR_ATTACHMENT15:
- case GL_COLOR_ATTACHMENT16:
- case GL_COLOR_ATTACHMENT17:
- case GL_COLOR_ATTACHMENT18:
- case GL_COLOR_ATTACHMENT19:
- case GL_COLOR_ATTACHMENT20:
- case GL_COLOR_ATTACHMENT21:
- case GL_COLOR_ATTACHMENT22:
- case GL_COLOR_ATTACHMENT23:
- case GL_COLOR_ATTACHMENT24:
- case GL_COLOR_ATTACHMENT25:
- case GL_COLOR_ATTACHMENT26:
- case GL_COLOR_ATTACHMENT27:
- case GL_COLOR_ATTACHMENT28:
- case GL_COLOR_ATTACHMENT29:
- case GL_COLOR_ATTACHMENT30:
- case GL_COLOR_ATTACHMENT31:
- if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
- {
- return error(GL_INVALID_ENUM);
- }
- attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
- attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
- attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
- renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
- break;
case GL_DEPTH:
+ case GL_STENCIL:
if(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
- // fall through
+
+ if(framebufferName != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ if(framebufferName == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if(clientVersion < 3)
+ {
+ return error(GL_INVALID_ENUM);
+ }
+
+ if(framebufferName == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
+ default:
+ if((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS)
+ {
+ if(framebufferName == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+ else return error(GL_INVALID_ENUM);
+ }
+
+ es2::Framebuffer *framebuffer = context->getFramebuffer(framebufferName);
+
+ GLenum attachmentType;
+ GLuint attachmentHandle;
+ GLint attachmentLayer;
+ Renderbuffer *renderbuffer = nullptr;
+ switch(attachment)
+ {
+ case GL_BACK:
+ attachmentType = framebuffer->getColorbufferType(0);
+ attachmentHandle = framebuffer->getColorbufferName(0);
+ attachmentLayer = framebuffer->getColorbufferLayer(0);
+ renderbuffer = framebuffer->getColorbuffer(0);
+ break;
+ case GL_DEPTH:
case GL_DEPTH_ATTACHMENT:
attachmentType = framebuffer->getDepthbufferType();
attachmentHandle = framebuffer->getDepthbufferName();
@@ -2862,11 +2781,6 @@
renderbuffer = framebuffer->getDepthbuffer();
break;
case GL_STENCIL:
- if(clientVersion < 3)
- {
- return error(GL_INVALID_ENUM);
- }
- // fall through
case GL_STENCIL_ATTACHMENT:
attachmentType = framebuffer->getStencilbufferType();
attachmentHandle = framebuffer->getStencilbufferName();
@@ -2874,26 +2788,32 @@
renderbuffer = framebuffer->getStencilbuffer();
break;
case GL_DEPTH_STENCIL_ATTACHMENT:
- if(clientVersion >= 3)
+ attachmentType = framebuffer->getDepthbufferType();
+ attachmentHandle = framebuffer->getDepthbufferName();
+ attachmentLayer = framebuffer->getDepthbufferLayer();
+ renderbuffer = framebuffer->getDepthbuffer();
+
+ if(attachmentHandle != framebuffer->getStencilbufferName())
{
- attachmentType = framebuffer->getDepthbufferType();
- attachmentHandle = framebuffer->getDepthbufferName();
- attachmentLayer = framebuffer->getDepthbufferLayer();
- if(attachmentHandle != framebuffer->getStencilbufferName())
- {
- // Different attachments to DEPTH and STENCIL, query fails
- return error(GL_INVALID_OPERATION);
- }
- renderbuffer = framebuffer->getDepthbuffer();
+ // Different attachments to DEPTH and STENCIL, query fails
+ return error(GL_INVALID_OPERATION);
}
- else return error(GL_INVALID_ENUM);
break;
default:
- return error(GL_INVALID_ENUM);
+ ASSERT((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS);
+ attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
+ attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
+ attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
+ renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
+ break;
}
GLenum attachmentObjectType = GL_NONE; // Type category
- if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
+ if(framebufferName == 0)
+ {
+ attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
+ }
+ else if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
{
attachmentObjectType = attachmentType;
}
@@ -2911,7 +2831,7 @@
*params = attachmentObjectType;
break;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- if(Framebuffer::IsRenderbuffer(attachmentObjectType) || attachmentObjectType == GL_TEXTURE)
+ if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
{
*params = attachmentHandle;
}
@@ -2923,7 +2843,7 @@
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
if(attachmentObjectType == GL_TEXTURE)
{
- *params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
+ *params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // glFramebufferTexture2D does not allow level to be set to anything else in GL ES 2.0
}
else
{
@@ -3003,12 +2923,12 @@
return error(GL_INVALID_OPERATION);
}
- *params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);
+ *params = GetComponentType(renderbuffer->getFormat(), attachment);
break;
case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
if(clientVersion >= 3)
{
- *params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added
+ *params = GetColorEncoding(renderbuffer->getFormat());
}
else return error(GL_INVALID_ENUM);
break;
@@ -3030,7 +2950,6 @@
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
*params = GL_NONE;
break;
-
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
if(clientVersion < 3)
{
@@ -3038,7 +2957,6 @@
}
*params = 0;
break;
-
default:
if(clientVersion < 3)
{
@@ -3128,7 +3046,7 @@
{
if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
{
- params[i] = convert_float_int(floatParams[i]);
+ params[i] = convert_float_fixed(floatParams[i]);
}
else
{
@@ -3369,14 +3287,19 @@
{
case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
- case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
+ case GL_RENDERBUFFER_INTERNAL_FORMAT:
+ {
+ GLint internalformat = renderbuffer->getFormat();
+ *params = (internalformat == GL_NONE) ? GL_RGBA4 : internalformat;
+ }
+ break;
case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
- case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
+ case GL_RENDERBUFFER_SAMPLES: *params = renderbuffer->getSamples(); break;
default:
return error(GL_INVALID_ENUM);
}
@@ -3596,9 +3519,12 @@
texture = context->getTexture2DArray();
}
break;
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
texture = context->getTexture3D();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -3749,9 +3675,12 @@
texture = context->getTexture2DArray();
}
break;
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
texture = context->getTexture3D();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -4104,22 +4033,7 @@
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
if(clientVersion >= 3)
{
- switch(attribState.mType)
- {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT:
- case GL_FIXED:
- *params = (GLfloat)GL_TRUE;
- break;
- default:
- *params = (GLfloat)GL_FALSE;
- break;
- }
+ *params = (GLfloat)(attribState.mPureInteger ? GL_TRUE : GL_FALSE);
break;
}
else return error(GL_INVALID_ENUM);
@@ -4178,22 +4092,7 @@
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
if(clientVersion >= 3)
{
- switch(attribState.mType)
- {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT:
- case GL_FIXED:
- *params = GL_TRUE;
- break;
- default:
- *params = GL_FALSE;
- break;
- }
+ *params = (attribState.mPureInteger ? GL_TRUE : GL_FALSE);
break;
}
else return error(GL_INVALID_ENUM);
@@ -4239,19 +4138,23 @@
}
es2::Context *context = es2::getContext();
- switch(target)
+
+ if(context)
{
- case GL_GENERATE_MIPMAP_HINT:
- if(context) context->setGenerateMipmapHint(mode);
- break;
- case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
- if(context) context->setFragmentShaderDerivativeHint(mode);
- break;
- case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
- if(context) context->setTextureFilteringHint(mode);
- break;
- default:
- return error(GL_INVALID_ENUM);
+ switch(target)
+ {
+ case GL_GENERATE_MIPMAP_HINT:
+ context->setGenerateMipmapHint(mode);
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ context->setFragmentShaderDerivativeHint(mode);
+ break;
+ case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
+ context->setTextureFilteringHint(mode);
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
}
}
@@ -4494,6 +4397,15 @@
}
}
+ if(programObject == context->getCurrentProgram())
+ {
+ es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+ if(transformFeedback && transformFeedback->isActive())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+
programObject->link();
}
}
@@ -4688,22 +4600,23 @@
return error(GL_INVALID_ENUM);
}
- if(width < 0 || height < 0 || samples < 0)
+ if(width < 0 || height < 0 || samples < 0 ||
+ width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
+ height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
{
return error(GL_INVALID_VALUE);
}
+ if(samples > es2::IMPLEMENTATION_MAX_SAMPLES ||
+ (IsNonNormalizedInteger(internalformat) && samples > 0))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
es2::Context *context = es2::getContext();
if(context)
{
- if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
- height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
- samples > es2::IMPLEMENTATION_MAX_SAMPLES)
- {
- return error(GL_INVALID_VALUE);
- }
-
GLuint handle = context->getRenderbufferName();
if(handle == 0)
{
@@ -4712,7 +4625,7 @@
GLint clientVersion = context->getClientVersion();
- if(IsColorRenderable(internalformat, clientVersion, false))
+ if(IsColorRenderable(internalformat, clientVersion))
{
context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
}
@@ -5040,26 +4953,30 @@
if(context)
{
+ // Core OpenGL ES 2.0 requires format and internalformat to be equal (checked below),
+ // but GL_APPLE_texture_format_BGRA8888 allows (only) GL_BGRA_EXT / GL_RGBA, while
+ // GL_EXT_texture_format_BGRA8888 also allows GL_BGRA_EXT / GL_BGRA_EXT.
+ if(format == GL_BGRA_EXT && internalformat == GL_RGBA)
+ {
+ internalformat = GL_BGRA_EXT;
+ }
+
GLint clientVersion = context->getClientVersion();
if(clientVersion < 3)
{
- if(internalformat != (GLint)format)
+ if((internalformat != (GLint)format) &&
+ !((type == GL_FLOAT) && (format == GL_RGBA) && (internalformat == GL_RGBA32F))) // CHROMIUM_color_buffer_float_rgba
{
return error(GL_INVALID_OPERATION);
}
}
- GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);
- if(validationError != GL_NONE)
+ GLenum validationError = ValidateTextureFormatType(format, type, internalformat, target, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
- if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
- {
- return;
- }
-
if(border != 0)
{
return error(GL_INVALID_VALUE);
@@ -5067,6 +4984,12 @@
switch(target)
{
+ case GL_TEXTURE_RECTANGLE_ARB:
+ if(level != 0)
+ {
+ return error(GL_INVALID_VALUE); // Defining level other than 0 is not allowed
+ }
+ // Fall through
case GL_TEXTURE_2D:
if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
@@ -5095,18 +5018,24 @@
return error(GL_INVALID_ENUM);
}
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
- if(target == GL_TEXTURE_2D)
+ validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
+ if(validationError != GL_NO_ERROR)
{
- es2::Texture2D *texture = context->getTexture2D();
+ return error(validationError);
+ }
+
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ es2::Texture2D *texture = context->getTexture2D(target);
if(!texture)
{
return error(GL_INVALID_OPERATION);
}
- texture->setImage(context, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
+ texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackParameters(), data);
}
else
{
@@ -5117,7 +5046,7 @@
return error(GL_INVALID_OPERATION);
}
- texture->setImage(context, target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
+ texture->setImage(target, level, width, height, sizedInternalFormat, format, type, context->getUnpackParameters(), data);
}
}
}
@@ -5149,7 +5078,7 @@
texture = context->getTexture2DArray();
}
break;
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
texture = context->getTexture3D();
break;
case GL_TEXTURE_CUBE_MAP:
@@ -5158,6 +5087,9 @@
case GL_TEXTURE_EXTERNAL_OES:
texture = context->getTextureExternal();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -5298,7 +5230,7 @@
texture = context->getTexture2DArray();
}
break;
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
texture = context->getTexture3D();
break;
case GL_TEXTURE_CUBE_MAP:
@@ -5307,6 +5239,9 @@
case GL_TEXTURE_EXTERNAL_OES:
texture = context->getTextureExternal();
break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ texture = context->getTexture2DRect();
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -5350,6 +5285,10 @@
}
break;
case GL_TEXTURE_BASE_LEVEL:
+ if((texture->getTarget() == GL_TEXTURE_RECTANGLE_ARB) && (param != 0))
+ {
+ return error(GL_INVALID_OPERATION); // Base level has to be 0
+ }
if(clientVersion < 3 || !texture->setBaseLevel(param))
{
return error(GL_INVALID_VALUE);
@@ -5448,51 +5387,45 @@
return error(GL_INVALID_VALUE);
}
- if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
- {
- return;
- }
-
- if(width == 0 || height == 0)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
{
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
-
- if(target == GL_TEXTURE_2D)
+ if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
{
- es2::Texture2D *texture = context->getTexture2D();
+ es2::Texture2D *texture = context->getTexture2D(target);
- GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
-
- if(validationError == GL_NONE)
- {
- texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
- }
- else
+ GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
+
+ validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
+ texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackParameters(), data);
}
else if(es2::IsCubemapTextureTarget(target))
{
es2::TextureCubeMap *texture = context->getTextureCubeMap();
- GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
-
- if(validationError == GL_NONE)
- {
- texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
- }
- else
+ GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
+
+ validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type));
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
+ texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackParameters(), data);
}
else UNREACHABLE(target);
}
@@ -5512,11 +5445,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5528,6 +5456,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform1fv(location, count, v))
{
return error(GL_INVALID_OPERATION);
@@ -5549,11 +5482,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5565,6 +5493,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform1iv(location, count, v))
{
return error(GL_INVALID_OPERATION);
@@ -5588,11 +5521,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5604,6 +5532,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform2fv(location, count, v))
{
return error(GL_INVALID_OPERATION);
@@ -5627,11 +5560,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5643,6 +5571,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform2iv(location, count, v))
{
return error(GL_INVALID_OPERATION);
@@ -5666,11 +5599,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5682,6 +5610,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform3fv(location, count, v))
{
return error(GL_INVALID_OPERATION);
@@ -5705,11 +5638,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5721,6 +5649,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform3iv(location, count, v))
{
return error(GL_INVALID_OPERATION);
@@ -5744,11 +5677,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5760,6 +5688,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform4fv(location, count, v))
{
return error(GL_INVALID_OPERATION);
@@ -5783,11 +5716,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5799,6 +5727,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform4iv(location, count, v))
{
return error(GL_INVALID_OPERATION);
@@ -5816,11 +5749,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5837,6 +5765,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix2fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -5854,11 +5787,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5875,6 +5803,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix3fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -5892,11 +5825,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -5913,6 +5841,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix4fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -5928,6 +5861,12 @@
if(context)
{
+ es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+ if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
es2::Program *programObject = context->getProgram(program);
if(!programObject && program != 0)
@@ -6180,7 +6119,15 @@
if(context)
{
- context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
+ es2::VertexArray* vertexArray = context->getCurrentVertexArray();
+ if((context->getArrayBufferName() == 0) && vertexArray && (vertexArray->name != 0) && ptr)
+ {
+ // GL_INVALID_OPERATION is generated if a non-zero vertex array object is bound, zero is bound
+ // to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.
+ return error(GL_INVALID_OPERATION);
+ }
+
+ context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), false, stride, ptr);
}
}
@@ -6262,7 +6209,7 @@
switch(target)
{
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
switch(format)
{
case GL_DEPTH_COMPONENT:
@@ -6276,9 +6223,15 @@
return error(GL_INVALID_ENUM);
}
- if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
+ if(internalformat != format)
{
- return;
+ return error(GL_INVALID_OPERATION);
+ }
+
+ GLenum validationError = ValidateTextureFormatType(format, type, internalformat, target, egl::getClientVersion());
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
}
if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
@@ -6308,7 +6261,14 @@
return error(GL_INVALID_OPERATION);
}
- texture->setImage(context, level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), context->getPixels(data));
+ GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
+ texture->setImage(level, width, height, depth, sizedInternalFormat, format, type, context->getUnpackParameters(), data);
}
}
@@ -6321,17 +6281,12 @@
switch(target)
{
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
break;
default:
return error(GL_INVALID_ENUM);
}
- if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
- {
- return;
- }
-
if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
{
return error(GL_INVALID_VALUE);
@@ -6348,17 +6303,19 @@
{
es2::Texture3D *texture = context->getTexture3D();
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
-
- GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
- if(validationError == GL_NONE)
- {
- texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
- }
- else
+ GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
+
+ validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
+ texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackParameters(), data);
}
}
@@ -6370,7 +6327,7 @@
switch(target)
{
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
break;
default:
return error(GL_INVALID_ENUM);
@@ -6401,14 +6358,13 @@
es2::Texture3D *texture = context->getTexture3D();
- GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
-
- if(validationError != GL_NONE)
+ GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
- texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
+ texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
}
}
@@ -6420,7 +6376,7 @@
switch(target)
{
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
break;
default:
return error(GL_INVALID_ENUM);
@@ -6437,25 +6393,12 @@
return error(GL_INVALID_VALUE);
}
- switch(internalformat)
+ if(!IsCompressed(internalformat, egl::getClientVersion()))
{
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT32_OES:
- case GL_DEPTH_STENCIL_OES:
- case GL_DEPTH24_STENCIL8_OES:
- return error(GL_INVALID_OPERATION);
- default:
- {
- GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
- if(validationError != GL_NONE)
- {
- return error(validationError);
- }
- }
+ return error(GL_INVALID_ENUM);
}
- if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
+ if(imageSize != gl::ComputeCompressedSize(width, height, internalformat) * depth)
{
return error(GL_INVALID_VALUE);
}
@@ -6471,6 +6414,13 @@
return error(GL_INVALID_OPERATION);
}
+ GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
+
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
}
}
@@ -6484,7 +6434,7 @@
switch(target)
{
- case GL_TEXTURE_3D_OES:
+ case GL_TEXTURE_3D:
break;
default:
return error(GL_INVALID_ENUM);
@@ -6500,15 +6450,14 @@
return error(GL_INVALID_VALUE);
}
- GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
- if(validationError != GL_NONE)
+ if(!IsCompressed(format, egl::getClientVersion()))
{
- return error(validationError);
+ return error(GL_INVALID_ENUM);
}
- if(width == 0 || height == 0 || depth == 0 || !data)
+ if(imageSize != gl::ComputeCompressedSize(width, height, format) * depth)
{
- return;
+ return error(GL_INVALID_VALUE);
}
es2::Context *context = es2::getContext();
@@ -6522,7 +6471,13 @@
return error(GL_INVALID_OPERATION);
}
- texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, context->getPixels(data));
+ GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
+ texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
}
}
@@ -6531,7 +6486,7 @@
TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
"GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
- if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+ if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
{
return error(GL_INVALID_ENUM);
}
@@ -6560,8 +6515,8 @@
switch(textarget)
{
- case GL_TEXTURE_3D_OES:
- if(tex->getTarget() != GL_TEXTURE_3D_OES)
+ case GL_TEXTURE_3D:
+ if(tex->getTarget() != GL_TEXTURE_3D)
{
return error(GL_INVALID_OPERATION);
}
@@ -6578,7 +6533,7 @@
es2::Framebuffer *framebuffer = nullptr;
GLuint framebufferName = 0;
- if(target == GL_READ_FRAMEBUFFER_ANGLE)
+ if(target == GL_READ_FRAMEBUFFER)
{
framebuffer = context->getReadFramebuffer();
framebufferName = context->getReadFramebufferName();
@@ -6661,6 +6616,7 @@
switch(target)
{
case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_ARB:
case GL_TEXTURE_EXTERNAL_OES:
break;
default:
@@ -6671,14 +6627,7 @@
if(context)
{
- es2::Texture2D *texture = nullptr;
-
- switch(target)
- {
- case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
- case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
- default: UNREACHABLE(target);
- }
+ es2::Texture2D *texture = context->getTexture2D(target);
if(!texture)
{
@@ -6858,71 +6807,327 @@
extern "C" NO_SANITIZE_FUNCTION __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
{
- struct Extension
+ struct Function
{
const char *name;
__eglMustCastToProperFunctionPointerType address;
};
- static const Extension glExtensions[] =
+ struct CompareFunctor
{
- #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
-
- EXTENSION(glTexImage3DOES),
- EXTENSION(glBlitFramebufferANGLE),
- EXTENSION(glBlitFramebufferNV),
- EXTENSION(glRenderbufferStorageMultisampleANGLE),
- EXTENSION(glDeleteFencesNV),
- EXTENSION(glGenFencesNV),
- EXTENSION(glIsFenceNV),
- EXTENSION(glTestFenceNV),
- EXTENSION(glGetFenceivNV),
- EXTENSION(glFinishFenceNV),
- EXTENSION(glSetFenceNV),
- EXTENSION(glGetGraphicsResetStatusEXT),
- EXTENSION(glReadnPixelsEXT),
- EXTENSION(glGetnUniformfvEXT),
- EXTENSION(glGetnUniformivEXT),
- EXTENSION(glGenQueriesEXT),
- EXTENSION(glDeleteQueriesEXT),
- EXTENSION(glIsQueryEXT),
- EXTENSION(glBeginQueryEXT),
- EXTENSION(glEndQueryEXT),
- EXTENSION(glGetQueryivEXT),
- EXTENSION(glGetQueryObjectuivEXT),
- EXTENSION(glEGLImageTargetTexture2DOES),
- EXTENSION(glEGLImageTargetRenderbufferStorageOES),
- EXTENSION(glDrawElementsInstancedEXT),
- EXTENSION(glDrawArraysInstancedEXT),
- EXTENSION(glVertexAttribDivisorEXT),
- EXTENSION(glDrawArraysInstancedANGLE),
- EXTENSION(glDrawElementsInstancedANGLE),
- EXTENSION(glVertexAttribDivisorANGLE),
- EXTENSION(glIsRenderbufferOES),
- EXTENSION(glBindRenderbufferOES),
- EXTENSION(glDeleteRenderbuffersOES),
- EXTENSION(glGenRenderbuffersOES),
- EXTENSION(glRenderbufferStorageOES),
- EXTENSION(glGetRenderbufferParameterivOES),
- EXTENSION(glIsFramebufferOES),
- EXTENSION(glBindFramebufferOES),
- EXTENSION(glDeleteFramebuffersOES),
- EXTENSION(glGenFramebuffersOES),
- EXTENSION(glCheckFramebufferStatusOES),
- EXTENSION(glFramebufferRenderbufferOES),
- EXTENSION(glFramebufferTexture2DOES),
- EXTENSION(glGetFramebufferAttachmentParameterivOES),
- EXTENSION(glGenerateMipmapOES),
- EXTENSION(glDrawBuffersEXT),
-
- #undef EXTENSION
+ bool operator()(const Function &a, const Function &b) const
+ {
+ return strcmp(a.name, b.name) < 0;
+ }
};
- for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
+ // This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
+ // The Unix command "LC_COLLATE=C sort" will generate the correct order.
+ static const Function glFunctions[] =
{
- if(strcmp(procname, glExtensions[ext].name) == 0)
+ #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
+
+ FUNCTION(glActiveTexture),
+ FUNCTION(glAttachShader),
+ FUNCTION(glBeginQuery),
+ FUNCTION(glBeginQueryEXT),
+ FUNCTION(glBeginTransformFeedback),
+ FUNCTION(glBindAttribLocation),
+ FUNCTION(glBindBuffer),
+ FUNCTION(glBindBufferBase),
+ FUNCTION(glBindBufferRange),
+ FUNCTION(glBindFramebuffer),
+ FUNCTION(glBindFramebufferOES),
+ FUNCTION(glBindRenderbuffer),
+ FUNCTION(glBindRenderbufferOES),
+ FUNCTION(glBindSampler),
+ FUNCTION(glBindTexture),
+ FUNCTION(glBindTransformFeedback),
+ FUNCTION(glBindVertexArray),
+ FUNCTION(glBlendColor),
+ FUNCTION(glBlendEquation),
+ FUNCTION(glBlendEquationSeparate),
+ FUNCTION(glBlendFunc),
+ FUNCTION(glBlendFuncSeparate),
+ FUNCTION(glBlitFramebuffer),
+ FUNCTION(glBlitFramebufferANGLE),
+ FUNCTION(glBufferData),
+ FUNCTION(glBufferSubData),
+ FUNCTION(glCheckFramebufferStatus),
+ FUNCTION(glCheckFramebufferStatusOES),
+ FUNCTION(glClear),
+ FUNCTION(glClearBufferfi),
+ FUNCTION(glClearBufferfv),
+ FUNCTION(glClearBufferiv),
+ FUNCTION(glClearBufferuiv),
+ FUNCTION(glClearColor),
+ FUNCTION(glClearDepthf),
+ FUNCTION(glClearStencil),
+ FUNCTION(glClientWaitSync),
+ FUNCTION(glColorMask),
+ FUNCTION(glCompileShader),
+ FUNCTION(glCompressedTexImage2D),
+ FUNCTION(glCompressedTexImage3D),
+ FUNCTION(glCompressedTexSubImage2D),
+ FUNCTION(glCompressedTexSubImage3D),
+ FUNCTION(glCopyBufferSubData),
+ FUNCTION(glCopyTexImage2D),
+ FUNCTION(glCopyTexSubImage2D),
+ FUNCTION(glCopyTexSubImage3D),
+ FUNCTION(glCreateProgram),
+ FUNCTION(glCreateShader),
+ FUNCTION(glCullFace),
+ FUNCTION(glDeleteBuffers),
+ FUNCTION(glDeleteFencesNV),
+ FUNCTION(glDeleteFramebuffers),
+ FUNCTION(glDeleteFramebuffersOES),
+ FUNCTION(glDeleteProgram),
+ FUNCTION(glDeleteQueries),
+ FUNCTION(glDeleteQueriesEXT),
+ FUNCTION(glDeleteRenderbuffers),
+ FUNCTION(glDeleteRenderbuffersOES),
+ FUNCTION(glDeleteSamplers),
+ FUNCTION(glDeleteShader),
+ FUNCTION(glDeleteSync),
+ FUNCTION(glDeleteTextures),
+ FUNCTION(glDeleteTransformFeedbacks),
+ FUNCTION(glDeleteVertexArrays),
+ FUNCTION(glDepthFunc),
+ FUNCTION(glDepthMask),
+ FUNCTION(glDepthRangef),
+ FUNCTION(glDetachShader),
+ FUNCTION(glDisable),
+ FUNCTION(glDisableVertexAttribArray),
+ FUNCTION(glDrawArrays),
+ FUNCTION(glDrawArraysInstanced),
+ FUNCTION(glDrawBuffers),
+ FUNCTION(glDrawBuffersEXT),
+ FUNCTION(glDrawElements),
+ FUNCTION(glDrawElementsInstanced),
+ FUNCTION(glDrawRangeElements),
+ FUNCTION(glEGLImageTargetRenderbufferStorageOES),
+ FUNCTION(glEGLImageTargetTexture2DOES),
+ FUNCTION(glEnable),
+ FUNCTION(glEnableVertexAttribArray),
+ FUNCTION(glEndQuery),
+ FUNCTION(glEndQueryEXT),
+ FUNCTION(glEndTransformFeedback),
+ FUNCTION(glFenceSync),
+ FUNCTION(glFinish),
+ FUNCTION(glFinishFenceNV),
+ FUNCTION(glFlush),
+ FUNCTION(glFlushMappedBufferRange),
+ FUNCTION(glFramebufferRenderbuffer),
+ FUNCTION(glFramebufferRenderbufferOES),
+ FUNCTION(glFramebufferTexture2D),
+ FUNCTION(glFramebufferTexture2DOES),
+ FUNCTION(glFramebufferTextureLayer),
+ FUNCTION(glFrontFace),
+ FUNCTION(glGenBuffers),
+ FUNCTION(glGenFencesNV),
+ FUNCTION(glGenFramebuffers),
+ FUNCTION(glGenFramebuffersOES),
+ FUNCTION(glGenQueries),
+ FUNCTION(glGenQueriesEXT),
+ FUNCTION(glGenRenderbuffers),
+ FUNCTION(glGenRenderbuffersOES),
+ FUNCTION(glGenSamplers),
+ FUNCTION(glGenTextures),
+ FUNCTION(glGenTransformFeedbacks),
+ FUNCTION(glGenVertexArrays),
+ FUNCTION(glGenerateMipmap),
+ FUNCTION(glGenerateMipmapOES),
+ FUNCTION(glGetActiveAttrib),
+ FUNCTION(glGetActiveUniform),
+ FUNCTION(glGetActiveUniformBlockName),
+ FUNCTION(glGetActiveUniformBlockiv),
+ FUNCTION(glGetActiveUniformsiv),
+ FUNCTION(glGetAttachedShaders),
+ FUNCTION(glGetAttribLocation),
+ FUNCTION(glGetBooleanv),
+ FUNCTION(glGetBufferParameteri64v),
+ FUNCTION(glGetBufferParameteriv),
+ FUNCTION(glGetBufferPointerv),
+ FUNCTION(glGetError),
+ FUNCTION(glGetFenceivNV),
+ FUNCTION(glGetFloatv),
+ FUNCTION(glGetFragDataLocation),
+ FUNCTION(glGetFramebufferAttachmentParameteriv),
+ FUNCTION(glGetFramebufferAttachmentParameterivOES),
+ FUNCTION(glGetGraphicsResetStatusEXT),
+ FUNCTION(glGetInteger64i_v),
+ FUNCTION(glGetInteger64v),
+ FUNCTION(glGetIntegeri_v),
+ FUNCTION(glGetIntegerv),
+ FUNCTION(glGetInternalformativ),
+ FUNCTION(glGetProgramBinary),
+ FUNCTION(glGetProgramInfoLog),
+ FUNCTION(glGetProgramiv),
+ FUNCTION(glGetQueryObjectuiv),
+ FUNCTION(glGetQueryObjectuivEXT),
+ FUNCTION(glGetQueryiv),
+ FUNCTION(glGetQueryivEXT),
+ FUNCTION(glGetRenderbufferParameteriv),
+ FUNCTION(glGetRenderbufferParameterivOES),
+ FUNCTION(glGetSamplerParameterfv),
+ FUNCTION(glGetSamplerParameteriv),
+ FUNCTION(glGetShaderInfoLog),
+ FUNCTION(glGetShaderPrecisionFormat),
+ FUNCTION(glGetShaderSource),
+ FUNCTION(glGetShaderiv),
+ FUNCTION(glGetString),
+ FUNCTION(glGetStringi),
+ FUNCTION(glGetSynciv),
+ FUNCTION(glGetTexParameterfv),
+ FUNCTION(glGetTexParameteriv),
+ FUNCTION(glGetTransformFeedbackVarying),
+ FUNCTION(glGetUniformBlockIndex),
+ FUNCTION(glGetUniformIndices),
+ FUNCTION(glGetUniformLocation),
+ FUNCTION(glGetUniformfv),
+ FUNCTION(glGetUniformiv),
+ FUNCTION(glGetUniformuiv),
+ FUNCTION(glGetVertexAttribIiv),
+ FUNCTION(glGetVertexAttribIuiv),
+ FUNCTION(glGetVertexAttribPointerv),
+ FUNCTION(glGetVertexAttribfv),
+ FUNCTION(glGetVertexAttribiv),
+ FUNCTION(glGetnUniformfvEXT),
+ FUNCTION(glGetnUniformivEXT),
+ FUNCTION(glHint),
+ FUNCTION(glInvalidateFramebuffer),
+ FUNCTION(glInvalidateSubFramebuffer),
+ FUNCTION(glIsBuffer),
+ FUNCTION(glIsEnabled),
+ FUNCTION(glIsFenceNV),
+ FUNCTION(glIsFramebuffer),
+ FUNCTION(glIsFramebufferOES),
+ FUNCTION(glIsProgram),
+ FUNCTION(glIsQuery),
+ FUNCTION(glIsQueryEXT),
+ FUNCTION(glIsRenderbuffer),
+ FUNCTION(glIsRenderbufferOES),
+ FUNCTION(glIsSampler),
+ FUNCTION(glIsShader),
+ FUNCTION(glIsSync),
+ FUNCTION(glIsTexture),
+ FUNCTION(glIsTransformFeedback),
+ FUNCTION(glIsVertexArray),
+ FUNCTION(glLineWidth),
+ FUNCTION(glLinkProgram),
+ FUNCTION(glMapBufferRange),
+ FUNCTION(glPauseTransformFeedback),
+ FUNCTION(glPixelStorei),
+ FUNCTION(glPolygonOffset),
+ FUNCTION(glProgramBinary),
+ FUNCTION(glProgramParameteri),
+ FUNCTION(glReadBuffer),
+ FUNCTION(glReadPixels),
+ FUNCTION(glReadnPixelsEXT),
+ FUNCTION(glReleaseShaderCompiler),
+ FUNCTION(glRenderbufferStorage),
+ FUNCTION(glRenderbufferStorageMultisample),
+ FUNCTION(glRenderbufferStorageMultisampleANGLE),
+ FUNCTION(glRenderbufferStorageOES),
+ FUNCTION(glResumeTransformFeedback),
+ FUNCTION(glSampleCoverage),
+ FUNCTION(glSamplerParameterf),
+ FUNCTION(glSamplerParameterfv),
+ FUNCTION(glSamplerParameteri),
+ FUNCTION(glSamplerParameteriv),
+ FUNCTION(glScissor),
+ FUNCTION(glSetFenceNV),
+ FUNCTION(glShaderBinary),
+ FUNCTION(glShaderSource),
+ FUNCTION(glStencilFunc),
+ FUNCTION(glStencilFuncSeparate),
+ FUNCTION(glStencilMask),
+ FUNCTION(glStencilMaskSeparate),
+ FUNCTION(glStencilOp),
+ FUNCTION(glStencilOpSeparate),
+ FUNCTION(glTestFenceNV),
+ FUNCTION(glTexImage2D),
+ FUNCTION(glTexImage3D),
+ FUNCTION(glTexImage3DOES),
+ FUNCTION(glTexParameterf),
+ FUNCTION(glTexParameterfv),
+ FUNCTION(glTexParameteri),
+ FUNCTION(glTexParameteriv),
+ FUNCTION(glTexStorage2D),
+ FUNCTION(glTexStorage3D),
+ FUNCTION(glTexSubImage2D),
+ FUNCTION(glTexSubImage3D),
+ FUNCTION(glTransformFeedbackVaryings),
+ FUNCTION(glUniform1f),
+ FUNCTION(glUniform1fv),
+ FUNCTION(glUniform1i),
+ FUNCTION(glUniform1iv),
+ FUNCTION(glUniform1ui),
+ FUNCTION(glUniform1uiv),
+ FUNCTION(glUniform2f),
+ FUNCTION(glUniform2fv),
+ FUNCTION(glUniform2i),
+ FUNCTION(glUniform2iv),
+ FUNCTION(glUniform2ui),
+ FUNCTION(glUniform2uiv),
+ FUNCTION(glUniform3f),
+ FUNCTION(glUniform3fv),
+ FUNCTION(glUniform3i),
+ FUNCTION(glUniform3iv),
+ FUNCTION(glUniform3ui),
+ FUNCTION(glUniform3uiv),
+ FUNCTION(glUniform4f),
+ FUNCTION(glUniform4fv),
+ FUNCTION(glUniform4i),
+ FUNCTION(glUniform4iv),
+ FUNCTION(glUniform4ui),
+ FUNCTION(glUniform4uiv),
+ FUNCTION(glUniformBlockBinding),
+ FUNCTION(glUniformMatrix2fv),
+ FUNCTION(glUniformMatrix2x3fv),
+ FUNCTION(glUniformMatrix2x4fv),
+ FUNCTION(glUniformMatrix3fv),
+ FUNCTION(glUniformMatrix3x2fv),
+ FUNCTION(glUniformMatrix3x4fv),
+ FUNCTION(glUniformMatrix4fv),
+ FUNCTION(glUniformMatrix4x2fv),
+ FUNCTION(glUniformMatrix4x3fv),
+ FUNCTION(glUnmapBuffer),
+ FUNCTION(glUseProgram),
+ FUNCTION(glValidateProgram),
+ FUNCTION(glVertexAttrib1f),
+ FUNCTION(glVertexAttrib1fv),
+ FUNCTION(glVertexAttrib2f),
+ FUNCTION(glVertexAttrib2fv),
+ FUNCTION(glVertexAttrib3f),
+ FUNCTION(glVertexAttrib3fv),
+ FUNCTION(glVertexAttrib4f),
+ FUNCTION(glVertexAttrib4fv),
+ FUNCTION(glVertexAttribDivisor),
+ FUNCTION(glVertexAttribI4i),
+ FUNCTION(glVertexAttribI4iv),
+ FUNCTION(glVertexAttribI4ui),
+ FUNCTION(glVertexAttribI4uiv),
+ FUNCTION(glVertexAttribIPointer),
+ FUNCTION(glVertexAttribPointer),
+ FUNCTION(glViewport),
+ FUNCTION(glWaitSync),
+
+ #undef FUNCTION
+ };
+
+ static const size_t numFunctions = sizeof glFunctions / sizeof(Function);
+ static const Function *const glFunctionsEnd = glFunctions + numFunctions;
+
+ Function needle;
+ needle.name = procname;
+
+ if(procname && strncmp("gl", procname, 2) == 0)
+ {
+ const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor());
+ if(result != glFunctionsEnd && strcmp(procname, result->name) == 0)
{
- return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
+ return (__eglMustCastToProperFunctionPointerType)result->address;
}
}
diff --git a/src/OpenGL/libGLESv2/libGLESv2.hpp b/src/OpenGL/libGLESv2/libGLESv2.hpp
index 42febd8..cb14319 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.hpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.hpp
@@ -302,6 +302,8 @@
#else
const char *libGLESv2_lib[] = {"libGLES_V2_translator.dylib", "libGLESv2.dylib", "libswiftshader_libGLESv2.dylib"};
#endif
+ #elif defined(__Fuchsia__)
+ const char *libGLESv2_lib[] = {"libGLESv2.so"};
#else
#error "libGLESv2::loadExports unimplemented for this platform"
#endif
diff --git a/src/OpenGL/libGLESv2/exports.map b/src/OpenGL/libGLESv2/libGLESv2.lds
similarity index 99%
rename from src/OpenGL/libGLESv2/exports.map
rename to src/OpenGL/libGLESv2/libGLESv2.lds
index adc4ff5..483efc2 100644
--- a/src/OpenGL/libGLESv2/exports.map
+++ b/src/OpenGL/libGLESv2/libGLESv2.lds
@@ -302,4 +302,4 @@
local:
*;
-};
+};
\ No newline at end of file
diff --git a/src/OpenGL/libGLESv2/libGLESv2.vcxproj b/src/OpenGL/libGLESv2/libGLESv2.vcxproj
index bae560e..fcd5093 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.vcxproj
+++ b/src/OpenGL/libGLESv2/libGLESv2.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -30,41 +30,42 @@
<ProjectGuid>{B5871A7A-968C-42E3-A33B-981E6F448E78}</ProjectGuid>
<RootNamespace>libGLESv2</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -124,7 +125,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>$(SolutionDir)\src;$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;GL_API=;GL_APICALL=;GL_GLEXT_PROTOTYPES;NO_SANITIZE_FUNCTION=;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -137,6 +138,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -155,7 +157,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>$(SolutionDir)\src;$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;GL_API=;GL_APICALL=;GL_GLEXT_PROTOTYPES;NO_SANITIZE_FUNCTION=;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@@ -167,6 +169,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -204,6 +207,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -242,6 +246,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -280,6 +285,7 @@
<IntrinsicFunctions>false</IntrinsicFunctions>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -316,6 +322,7 @@
<IntrinsicFunctions>false</IntrinsicFunctions>
<TreatWarningAsError>true</TreatWarningAsError>
<DisableSpecificWarnings>5030;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -343,6 +350,7 @@
<ClCompile Include="Context.cpp" />
<ClCompile Include="..\common\debug.cpp" />
<ClCompile Include="Device.cpp" />
+ <ClCompile Include="entry_points.cpp" />
<ClCompile Include="Fence.cpp" />
<ClCompile Include="Framebuffer.cpp" />
<ClCompile Include="IndexDataManager.cpp" />
diff --git a/src/OpenGL/libGLESv2/libGLESv2.vcxproj.filters b/src/OpenGL/libGLESv2/libGLESv2.vcxproj.filters
index e297714..615363b 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.vcxproj.filters
+++ b/src/OpenGL/libGLESv2/libGLESv2.vcxproj.filters
@@ -77,6 +77,9 @@
<ClCompile Include="..\common\Image.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="entry_points.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Buffer.h">
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index f995d2d..f5f3264 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -24,6 +24,7 @@
#include "Texture.h"
#include "mathutil.h"
#include "TransformFeedback.h"
+#include "VertexArray.h"
#include "common/debug.h"
#include <GLES3/gl3.h>
@@ -33,15 +34,6 @@
using namespace es2;
-typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
-typedef std::map<InternalFormatTypePair, GLenum> FormatMap;
-
-// A helper function to insert data into the format map with fewer characters.
-static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)
-{
- map[InternalFormatTypePair(internalformat, type)] = format;
-}
-
static bool validImageSize(GLint level, GLsizei width, GLsizei height)
{
if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
@@ -52,290 +44,6 @@
return true;
}
-static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
-{
- GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);
- if(validationError != GL_NONE)
- {
- return error(validationError, false);
- }
-
- switch(textureFormat)
- {
- case GL_ALPHA:
- if(colorbufferFormat != GL_ALPHA &&
- colorbufferFormat != GL_RGBA &&
- colorbufferFormat != GL_RGBA4 &&
- colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8)
- {
- return error(GL_INVALID_OPERATION, false);
- }
- break;
- case GL_LUMINANCE:
- case GL_RGB:
- if(colorbufferFormat != GL_RGB &&
- colorbufferFormat != GL_RGB565 &&
- colorbufferFormat != GL_RGB8 &&
- colorbufferFormat != GL_RGBA &&
- colorbufferFormat != GL_RGBA4 &&
- colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8)
- {
- return error(GL_INVALID_OPERATION, false);
- }
- break;
- case GL_LUMINANCE_ALPHA:
- case GL_RGBA:
- if(colorbufferFormat != GL_RGBA &&
- colorbufferFormat != GL_RGBA4 &&
- colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8)
- {
- return error(GL_INVALID_OPERATION, false);
- }
- break;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_STENCIL:
- return error(GL_INVALID_OPERATION, false);
- default:
- return error(GL_INVALID_ENUM, false);
- }
- return true;
-}
-
-static FormatMap BuildFormatMap3D()
-{
- FormatMap map;
-
- // Internal format | Format | Type
- InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
- InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
- InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
- InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_R8, GL_RED, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_R8_SNORM, GL_RED, GL_BYTE);
- InsertFormatMapping(map, GL_R16F, GL_RED, GL_HALF_FLOAT);
- InsertFormatMapping(map, GL_R16F, GL_RED, GL_FLOAT);
- InsertFormatMapping(map, GL_R32F, GL_RED, GL_FLOAT);
- InsertFormatMapping(map, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_R8I, GL_RED_INTEGER, GL_BYTE);
- InsertFormatMapping(map, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT);
- InsertFormatMapping(map, GL_R16I, GL_RED_INTEGER, GL_SHORT);
- InsertFormatMapping(map, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT);
- InsertFormatMapping(map, GL_R32I, GL_RED_INTEGER, GL_INT);
- InsertFormatMapping(map, GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RG8_SNORM, GL_RG, GL_BYTE);
- InsertFormatMapping(map, GL_RG16F, GL_RG, GL_HALF_FLOAT);
- InsertFormatMapping(map, GL_RG16F, GL_RG, GL_FLOAT);
- InsertFormatMapping(map, GL_RG32F, GL_RG, GL_FLOAT);
- InsertFormatMapping(map, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RG8I, GL_RG_INTEGER, GL_BYTE);
- InsertFormatMapping(map, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT);
- InsertFormatMapping(map, GL_RG16I, GL_RG_INTEGER, GL_SHORT);
- InsertFormatMapping(map, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT);
- InsertFormatMapping(map, GL_RG32I, GL_RG_INTEGER, GL_INT);
- InsertFormatMapping(map, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
- InsertFormatMapping(map, GL_RGB8_SNORM, GL_RGB, GL_BYTE);
- InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV);
- InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT);
- InsertFormatMapping(map, GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT);
- InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV);
- InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT);
- InsertFormatMapping(map, GL_RGB9_E5, GL_RGB, GL_FLOAT);
- InsertFormatMapping(map, GL_RGB16F, GL_RGB, GL_HALF_FLOAT);
- InsertFormatMapping(map, GL_RGB16F, GL_RGB, GL_FLOAT);
- InsertFormatMapping(map, GL_RGB32F, GL_RGB, GL_FLOAT);
- InsertFormatMapping(map, GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGB8I, GL_RGB_INTEGER, GL_BYTE);
- InsertFormatMapping(map, GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT);
- InsertFormatMapping(map, GL_RGB16I, GL_RGB_INTEGER, GL_SHORT);
- InsertFormatMapping(map, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT);
- InsertFormatMapping(map, GL_RGB32I, GL_RGB_INTEGER, GL_INT);
- InsertFormatMapping(map, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
- InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
- InsertFormatMapping(map, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE);
- InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
- InsertFormatMapping(map, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
- InsertFormatMapping(map, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT);
- InsertFormatMapping(map, GL_RGBA16F, GL_RGBA, GL_FLOAT);
- InsertFormatMapping(map, GL_RGBA32F, GL_RGBA, GL_FLOAT);
- InsertFormatMapping(map, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE);
- InsertFormatMapping(map, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE);
- InsertFormatMapping(map, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV);
- InsertFormatMapping(map, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT);
- InsertFormatMapping(map, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT);
- InsertFormatMapping(map, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
- InsertFormatMapping(map, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
-
- InsertFormatMapping(map, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
- InsertFormatMapping(map, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
- InsertFormatMapping(map, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
- InsertFormatMapping(map, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
- InsertFormatMapping(map, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
- InsertFormatMapping(map, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
- InsertFormatMapping(map, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
-
- return map;
-}
-
-static bool ValidateType3D(GLenum type)
-{
- switch(type)
- {
- case GL_UNSIGNED_BYTE:
- case GL_BYTE:
- case GL_UNSIGNED_SHORT:
- case GL_SHORT:
- case GL_UNSIGNED_INT:
- case GL_INT:
- case GL_HALF_FLOAT:
- case GL_FLOAT:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT_10F_11F_11F_REV:
- case GL_UNSIGNED_INT_5_9_9_9_REV:
- case GL_UNSIGNED_INT_24_8:
- case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
- return true;
- default:
- break;
- }
- return false;
-}
-
-static bool ValidateFormat3D(GLenum format)
-{
- switch(format)
- {
- case GL_RED:
- case GL_RG:
- case GL_RGB:
- case GL_RGBA:
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_STENCIL:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE:
- case GL_ALPHA:
- case GL_RED_INTEGER:
- case GL_RG_INTEGER:
- case GL_RGB_INTEGER:
- case GL_RGBA_INTEGER:
- return true;
- default:
- break;
- }
- return false;
-}
-
-static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)
-{
- static const FormatMap formatMap = BuildFormatMap3D();
- FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));
- if(iter != formatMap.end())
- {
- return iter->second == format;
- }
- return false;
-}
-
-typedef std::map<GLenum, GLenum> FormatMapStorage;
-
-// A helper function to insert data into the format map with fewer characters.
-static void InsertFormatStorageMapping(FormatMapStorage& map, GLenum internalformat, GLenum type)
-{
- map[internalformat] = type;
-}
-
-static FormatMapStorage BuildFormatMapStorage2D()
-{
- FormatMapStorage map;
-
- // Internal format | Type
- InsertFormatStorageMapping(map, GL_R8, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_R8_SNORM, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_R16F, GL_HALF_FLOAT);
- InsertFormatStorageMapping(map, GL_R32F, GL_FLOAT);
- InsertFormatStorageMapping(map, GL_R8UI, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_R8I, GL_BYTE);
- InsertFormatStorageMapping(map, GL_R16UI, GL_UNSIGNED_SHORT);
- InsertFormatStorageMapping(map, GL_R16I, GL_SHORT);
- InsertFormatStorageMapping(map, GL_R32UI, GL_UNSIGNED_INT);
- InsertFormatStorageMapping(map, GL_R32I, GL_INT);
- InsertFormatStorageMapping(map, GL_RG8, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_RG8_SNORM, GL_BYTE);
- InsertFormatStorageMapping(map, GL_RG16F, GL_HALF_FLOAT);
- InsertFormatStorageMapping(map, GL_RG32F, GL_FLOAT);
- InsertFormatStorageMapping(map, GL_RG8UI, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_RG8I, GL_BYTE);
- InsertFormatStorageMapping(map, GL_RG16UI, GL_UNSIGNED_SHORT);
- InsertFormatStorageMapping(map, GL_RG16I, GL_SHORT);
- InsertFormatStorageMapping(map, GL_RG32UI, GL_UNSIGNED_INT);
- InsertFormatStorageMapping(map, GL_RG32I, GL_INT);
- InsertFormatStorageMapping(map, GL_RGB8, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_SRGB8, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5);
- InsertFormatStorageMapping(map, GL_RGB8_SNORM, GL_BYTE);
- InsertFormatStorageMapping(map, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV);
- InsertFormatStorageMapping(map, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV);
- InsertFormatStorageMapping(map, GL_RGB16F, GL_HALF_FLOAT);
- InsertFormatStorageMapping(map, GL_RGB32F, GL_FLOAT);
- InsertFormatStorageMapping(map, GL_RGB8UI, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_RGB8I, GL_BYTE);
- InsertFormatStorageMapping(map, GL_RGB16UI, GL_UNSIGNED_SHORT);
- InsertFormatStorageMapping(map, GL_RGB16I, GL_SHORT);
- InsertFormatStorageMapping(map, GL_RGB32UI, GL_UNSIGNED_INT);
- InsertFormatStorageMapping(map, GL_RGB32I, GL_INT);
- InsertFormatStorageMapping(map, GL_RGBA8, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_RGBA8_SNORM, GL_BYTE);
- InsertFormatStorageMapping(map, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1);
- InsertFormatStorageMapping(map, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4);
- InsertFormatStorageMapping(map, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV);
- InsertFormatStorageMapping(map, GL_RGBA16F, GL_HALF_FLOAT);
- InsertFormatStorageMapping(map, GL_RGBA32F, GL_FLOAT);
- InsertFormatStorageMapping(map, GL_RGBA8UI, GL_UNSIGNED_BYTE);
- InsertFormatStorageMapping(map, GL_RGBA8I, GL_BYTE);
- InsertFormatStorageMapping(map, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV);
- InsertFormatStorageMapping(map, GL_RGBA16UI, GL_UNSIGNED_SHORT);
- InsertFormatStorageMapping(map, GL_RGBA16I, GL_SHORT);
- InsertFormatStorageMapping(map, GL_RGBA32UI, GL_UNSIGNED_INT);
- InsertFormatStorageMapping(map, GL_RGBA32I, GL_INT);
-
- InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT);
- InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT);
- InsertFormatStorageMapping(map, GL_DEPTH_COMPONENT32F, GL_FLOAT);
- InsertFormatStorageMapping(map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8);
- InsertFormatStorageMapping(map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
-
- return map;
-}
-
-static bool GetStorageType(GLenum internalformat, GLenum& type)
-{
- static const FormatMapStorage formatMap = BuildFormatMapStorage2D();
- FormatMapStorage::const_iterator iter = formatMap.find(internalformat);
- if(iter != formatMap.end())
- {
- type = iter->second;
- return true;
- }
- return false;
-}
-
static bool ValidateQueryTarget(GLenum target)
{
switch(target)
@@ -560,7 +268,7 @@
GLuint index = (src - GL_COLOR_ATTACHMENT0);
if(index >= MAX_COLOR_ATTACHMENTS)
{
- return error(GL_INVALID_ENUM);
+ return error(GL_INVALID_OPERATION);
}
if(readFramebufferName == 0)
{
@@ -570,7 +278,7 @@
}
break;
default:
- error(GL_INVALID_ENUM);
+ return error(GL_INVALID_ENUM);
}
}
}
@@ -640,11 +348,6 @@
return error(GL_INVALID_ENUM);
}
- if(!ValidateType3D(type) || !ValidateFormat3D(format))
- {
- return error(GL_INVALID_ENUM);
- }
-
if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
{
return error(GL_INVALID_VALUE);
@@ -661,15 +364,16 @@
return error(GL_INVALID_VALUE);
}
- if(!ValidateInternalFormat3D(internalformat, format, type))
- {
- return error(GL_INVALID_OPERATION);
- }
-
es2::Context *context = es2::getContext();
if(context)
{
+ GLenum validationError = ValidateTextureFormatType(format, type, internalformat, target, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
if(!texture)
@@ -677,7 +381,14 @@
return error(GL_INVALID_OPERATION);
}
- texture->setImage(context, level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), context->getPixels(data));
+ validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
+ texture->setImage(level, width, height, depth, sizedInternalFormat, format, type, context->getUnpackParameters(), data);
}
}
@@ -697,11 +408,6 @@
return error(GL_INVALID_ENUM);
}
- if(!ValidateType3D(type) || !ValidateFormat3D(format))
- {
- return error(GL_INVALID_ENUM);
- }
-
if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
{
return error(GL_INVALID_VALUE);
@@ -718,17 +424,19 @@
{
es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
-
- GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
- if(validationError == GL_NONE)
- {
- texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), context->getPixels(data));
- }
- else
+ GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
+
+ validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type));
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
+ texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackParameters(), data);
}
}
@@ -778,20 +486,20 @@
GLenum colorbufferFormat = source->getFormat();
es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
- GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
- if(validationError != GL_NONE)
+ GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion());
+ if(validationError != GL_NO_ERROR)
{
return error(validationError);
}
GLenum textureFormat = texture->getFormat(target, level);
- if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
+ if(!ValidateCopyFormats(textureFormat, colorbufferFormat))
{
return;
}
- texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
+ texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
}
}
@@ -821,25 +529,12 @@
return error(GL_INVALID_VALUE);
}
- switch(internalformat)
+ if(!IsCompressed(internalformat, egl::getClientVersion()))
{
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT32_OES:
- case GL_DEPTH_STENCIL:
- case GL_DEPTH24_STENCIL8:
- return error(GL_INVALID_OPERATION);
- default:
- {
- GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
- if(validationError != GL_NONE)
- {
- return error(validationError);
- }
- }
+ return error(GL_INVALID_ENUM);
}
- if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
+ if(imageSize != gl::ComputeCompressedSize(width, height, internalformat) * depth)
{
return error(GL_INVALID_VALUE);
}
@@ -855,6 +550,12 @@
return error(GL_INVALID_OPERATION);
}
+ GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
}
}
@@ -885,15 +586,44 @@
return error(GL_INVALID_VALUE);
}
- GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
- if(validationError != GL_NONE)
+ if(!IsCompressed(format, egl::getClientVersion()))
{
- return error(validationError);
+ return error(GL_INVALID_ENUM);
}
- if(width == 0 || height == 0 || depth == 0 || !data)
+ if(imageSize != gl::ComputeCompressedSize(width, height, format) * depth)
{
- return;
+ return error(GL_INVALID_VALUE);
+ }
+
+ bool is_ETC2_EAC = false;
+ switch(format)
+ {
+ case GL_COMPRESSED_R11_EAC:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ case GL_COMPRESSED_RG11_EAC:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ if(target != GL_TEXTURE_2D_ARRAY)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if(((width % 4) != 0) || ((height % 4) != 0) ||
+ ((xoffset % 4) != 0) || ((yoffset % 4) != 0))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ is_ETC2_EAC = true;
+ break;
+ default:
+ break;
}
es2::Context *context = es2::getContext();
@@ -907,7 +637,23 @@
return error(GL_INVALID_OPERATION);
}
- texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, context->getPixels(data));
+ GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize);
+ if(validationError != GL_NO_ERROR)
+ {
+ return error(validationError);
+ }
+
+ if(is_ETC2_EAC)
+ {
+ if(((width + xoffset) != texture->getWidth(target, level)) ||
+ ((height + yoffset) != texture->getHeight(target, level)) ||
+ ((depth + zoffset) != texture->getDepth(target, level)))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+
+ texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
}
}
@@ -1096,6 +842,12 @@
return error(GL_INVALID_OPERATION, GL_TRUE);
}
+ if(!buffer->isMapped())
+ {
+ // Already unmapped
+ return error(GL_INVALID_OPERATION, GL_TRUE);
+ }
+
return buffer->unmap() ? GL_TRUE : GL_FALSE;
}
@@ -1233,11 +985,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -1249,6 +996,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix2x3fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -1265,11 +1017,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -1281,6 +1028,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix3x2fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -1297,11 +1049,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -1313,6 +1060,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix2x4fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -1329,11 +1081,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -1345,6 +1092,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix4x2fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -1361,11 +1113,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -1377,6 +1124,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix3x4fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -1393,11 +1145,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -1409,6 +1156,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniformMatrix4x3fv(location, count, transpose, value))
{
return error(GL_INVALID_OPERATION);
@@ -1426,7 +1178,12 @@
switch(filter)
{
case GL_NEAREST:
+ break;
case GL_LINEAR:
+ if((mask & GL_DEPTH_BUFFER_BIT) || (mask & GL_STENCIL_BUFFER_BIT))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
break;
default:
return error(GL_INVALID_ENUM);
@@ -1475,7 +1232,7 @@
{
if(!textureObject)
{
- return error(GL_INVALID_VALUE);
+ return error(GL_INVALID_OPERATION);
}
textarget = textureObject->getTarget();
@@ -1503,9 +1260,17 @@
{
case GL_DRAW_FRAMEBUFFER:
case GL_FRAMEBUFFER:
+ if(context->getDrawFramebufferName() == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
framebuffer = context->getDrawFramebuffer();
break;
case GL_READ_FRAMEBUFFER:
+ if(context->getReadFramebufferName() == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
framebuffer = context->getReadFramebuffer();
break;
default:
@@ -1574,6 +1339,27 @@
TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = %X)",
target, offset, length, access);
+ if((offset < 0) || (length < 0))
+ {
+ return error(GL_INVALID_VALUE, nullptr);
+ }
+
+ if(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)))
+ {
+ // Must be able to read or write the buffer
+ return error(GL_INVALID_OPERATION, nullptr);
+ }
+ else if((access & GL_MAP_READ_BIT) && (access & (GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT)))
+ {
+ // GL_MAP_INVALIDATE_RANGE_BIT, GL_MAP_INVALIDATE_BUFFER_BIT and GL_MAP_UNSYNCHRONIZED_BIT can't be used with GL_MAP_READ_BIT
+ return error(GL_INVALID_OPERATION, nullptr);
+ }
+ else if((!(access & GL_MAP_WRITE_BIT)) && (access & GL_MAP_FLUSH_EXPLICIT_BIT))
+ {
+ // GL_MAP_FLUSH_EXPLICIT_BIT can't be used without GL_MAP_WRITE_BIT
+ return error(GL_INVALID_OPERATION, nullptr);
+ }
+
es2::Context *context = es2::getContext();
if(context)
@@ -1590,10 +1376,16 @@
return error(GL_INVALID_OPERATION, nullptr);
}
- GLsizeiptr bufferSize = buffer->size();
- if((offset < 0) || (length < 0) || ((offset + length) > bufferSize))
+ if(buffer->isMapped())
{
- error(GL_INVALID_VALUE);
+ // It is an invalid operation to map an already mapped buffer
+ return error(GL_INVALID_OPERATION, nullptr);
+ }
+
+ GLsizeiptr bufferSize = buffer->size();
+ if((offset + length) > bufferSize)
+ {
+ return error(GL_INVALID_VALUE, nullptr);
}
if((access & ~(GL_MAP_READ_BIT |
@@ -1603,7 +1395,7 @@
GL_MAP_FLUSH_EXPLICIT_BIT |
GL_MAP_UNSYNCHRONIZED_BIT)) != 0)
{
- error(GL_INVALID_VALUE);
+ return error(GL_INVALID_VALUE, nullptr);
}
return buffer->mapRange(offset, length, access);
@@ -1617,6 +1409,11 @@
TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)",
target, offset, length);
+ if((offset < 0) || (length < 0))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
es2::Context *context = es2::getContext();
if(context)
@@ -1633,10 +1430,22 @@
return error(GL_INVALID_OPERATION);
}
- GLsizeiptr bufferSize = buffer->size();
- if((offset < 0) || (length < 0) || ((offset + length) > bufferSize))
+ if(!buffer->isMapped())
{
- error(GL_INVALID_VALUE);
+ // Buffer must be mapped
+ return error(GL_INVALID_OPERATION);
+ }
+
+ GLsizeiptr bufferSize = buffer->length();
+ if((offset + length) > bufferSize)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if(!(buffer->access() & GL_MAP_FLUSH_EXPLICIT_BIT))
+ {
+ // Flush must be explicitly allowed
+ return error(GL_INVALID_OPERATION);
}
buffer->flushMappedRange(offset, length);
@@ -1647,11 +1456,6 @@
{
TRACE("(GLuint array = %d)", array);
- if(array == 0)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -1775,7 +1579,7 @@
{
if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)
{
- data[i] = convert_float_int(floatParams[i]);
+ data[i] = convert_float_fixed(floatParams[i]);
}
else
{
@@ -2023,7 +1827,15 @@
if(context)
{
- context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, stride, pointer);
+ es2::VertexArray* vertexArray = context->getCurrentVertexArray();
+ if((context->getArrayBufferName() == 0) && vertexArray && (vertexArray->name != 0) && pointer)
+ {
+ // GL_INVALID_OPERATION is generated if a non-zero vertex array object is bound, zero is bound
+ // to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.
+ return error(GL_INVALID_OPERATION);
+ }
+
+ context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, true, stride, pointer);
}
}
@@ -2073,22 +1885,7 @@
}
break;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
- switch(attribState.mType)
- {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT:
- case GL_FIXED:
- *params = GL_TRUE;
- break;
- default:
- *params = GL_FALSE;
- break;
- }
+ *params = (attribState.mPureInteger ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
*params = attribState.mDivisor;
@@ -2144,22 +1941,7 @@
}
break;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
- switch(attribState.mType)
- {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT:
- case GL_FIXED:
- *params = GL_TRUE;
- break;
- default:
- *params = GL_FALSE;
- break;
- }
+ *params = (attribState.mPureInteger ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
*params = attribState.mDivisor;
@@ -2250,19 +2032,21 @@
if(context)
{
- if(program == 0)
- {
- return error(GL_INVALID_VALUE);
- }
-
es2::Program *programObject = context->getProgram(program);
- if(!programObject || !programObject->isLinked())
+ if(!programObject)
{
- return error(GL_INVALID_OPERATION);
+ if(context->getShader(program))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_VALUE);
+ }
}
- if(!programObject)
+ if(!programObject->isLinked())
{
return error(GL_INVALID_OPERATION);
}
@@ -2343,11 +2127,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -2359,6 +2138,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform1uiv(location, count, value))
{
return error(GL_INVALID_OPERATION);
@@ -2376,11 +2160,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -2392,6 +2171,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform2uiv(location, count, value))
{
return error(GL_INVALID_OPERATION);
@@ -2409,11 +2193,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -2425,6 +2204,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform3uiv(location, count, value))
{
return error(GL_INVALID_OPERATION);
@@ -2442,11 +2226,6 @@
return error(GL_INVALID_VALUE);
}
- if(location == -1)
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -2458,6 +2237,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(location == -1)
+ {
+ return;
+ }
+
if(!program->setUniform4uiv(location, count, value))
{
return error(GL_INVALID_OPERATION);
@@ -2682,7 +2466,14 @@
if(!programObject)
{
- return error(GL_INVALID_OPERATION);
+ if(context->getShader(program))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_VALUE);
+ }
}
if(!programObject->isLinked())
@@ -2735,7 +2526,14 @@
if(!programObject)
{
- return error(GL_INVALID_OPERATION);
+ if(context->getShader(program))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_VALUE);
+ }
}
for(int uniformId = 0; uniformId < uniformCount; uniformId++)
@@ -2769,7 +2567,14 @@
if(!programObject)
{
- return error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
+ if(context->getShader(program))
+ {
+ return error(GL_INVALID_OPERATION, GL_INVALID_INDEX);
+ }
+ else
+ {
+ return error(GL_INVALID_VALUE, GL_INVALID_INDEX);
+ }
}
return programObject->getUniformBlockIndex(uniformBlockName);
@@ -2999,10 +2804,20 @@
{
TRACE("(GLsync sync = %p)", sync);
+ if(!sync)
+ {
+ return;
+ }
+
es2::Context *context = es2::getContext();
if(context)
{
+ if(!context->getFenceSync(sync))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
context->deleteFenceSync(sync);
}
}
@@ -3013,7 +2828,7 @@
if((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
{
- error(GL_INVALID_VALUE);
+ return error(GL_INVALID_VALUE, GL_FALSE);
}
es2::Context *context = es2::getContext();
@@ -3109,7 +2924,7 @@
{
if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
{
- data[i] = (GLint64)(convert_float_int(floatParams[i]));
+ data[i] = (GLint64)(convert_float_fixed(floatParams[i]));
}
else
{
@@ -3192,7 +3007,7 @@
{
if(target == GL_DEPTH_RANGE || target == GL_COLOR_CLEAR_VALUE || target == GL_DEPTH_CLEAR_VALUE || target == GL_BLEND_COLOR)
{
- data[i] = (GLint64)(convert_float_int(floatParams[i]));
+ data[i] = (GLint64)(convert_float_fixed(floatParams[i]));
}
else
{
@@ -3391,11 +3206,6 @@
return error(GL_INVALID_ENUM);
}
- if(!ValidateTexParamParameters(pname, static_cast<GLint>(roundf(*param))))
- {
- return;
- }
-
es2::Context *context = es2::getContext();
if(context)
@@ -3405,7 +3215,10 @@
return error(GL_INVALID_OPERATION);
}
- context->samplerParameterf(sampler, pname, *param);
+ if(ValidateTexParamParameters(pname, static_cast<GLint>(roundf(*param))))
+ {
+ context->samplerParameterf(sampler, pname, *param);
+ }
}
}
@@ -3425,7 +3238,7 @@
{
if(!context->isSampler(sampler))
{
- return error(GL_INVALID_VALUE);
+ return error(GL_INVALID_OPERATION);
}
*params = context->getSamplerParameteri(sampler, pname);
@@ -3448,7 +3261,7 @@
{
if(!context->isSampler(sampler))
{
- return error(GL_INVALID_VALUE);
+ return error(GL_INVALID_OPERATION);
}
*params = context->getSamplerParameterf(sampler, pname);
@@ -3492,6 +3305,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(!context->isTransformFeedback(id))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
context->bindTransformFeedback(id);
}
}
@@ -3513,6 +3331,13 @@
{
if(ids[i] != 0)
{
+ es2::TransformFeedback *transformFeedbackObject = context->getTransformFeedback(ids[i]);
+
+ if(transformFeedbackObject && transformFeedbackObject->isActive())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
context->deleteTransformFeedback(ids[i]);
}
}
@@ -3615,7 +3440,20 @@
return error(GL_INVALID_VALUE);
}
- UNIMPLEMENTED();
+ es2::Context *context = es2::getContext();
+
+ if(context)
+ {
+ es2::Program *programObject = context->getProgram(program);
+
+ if(!programObject || !programObject->isLinked())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+
+ // SwiftShader doesn't return a program binary and sets the program binay size to 0, so any attempt at getting one is invalid.
+ return error(GL_INVALID_OPERATION);
}
GL_APICALL void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
@@ -3628,7 +3466,20 @@
return error(GL_INVALID_VALUE);
}
- UNIMPLEMENTED();
+ es2::Context *context = es2::getContext();
+
+ if(context)
+ {
+ es2::Program *programObject = context->getProgram(program);
+
+ if(!programObject)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+
+ // Regardless of what the binaryFormat is, it is unrecognized by SwiftShader, since it supports no format.
+ return error(GL_INVALID_ENUM);
}
GL_APICALL void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)
@@ -3644,12 +3495,16 @@
if(!programObject)
{
- return error(GL_INVALID_OPERATION);
+ return error(GL_INVALID_VALUE);
}
switch(pname)
{
case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
+ if((value != GL_TRUE) && (value != GL_FALSE))
+ {
+ return error(GL_INVALID_VALUE);
+ }
programObject->setBinaryRetrievable(value != GL_FALSE);
break;
default:
@@ -3686,6 +3541,7 @@
case GL_DRAW_FRAMEBUFFER:
case GL_FRAMEBUFFER:
framebuffer = context->getDrawFramebuffer();
+ break;
case GL_READ_FRAMEBUFFER:
framebuffer = context->getReadFramebuffer();
break;
@@ -3738,7 +3594,7 @@
TRACE("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
target, levels, internalformat, width, height);
- if(width < 1 || height < 1 || levels < 1)
+ if(width < 1 || height < 1 || levels < 1 || ((target == GL_TEXTURE_RECTANGLE_ARB) && (levels != 1)))
{
return error(GL_INVALID_VALUE);
}
@@ -3748,8 +3604,8 @@
return error(GL_INVALID_OPERATION);
}
- GLenum type;
- if(!GetStorageType(internalformat, type))
+ bool isCompressed = IsCompressed(internalformat, egl::getClientVersion());
+ if(!IsSizedInternalFormat(internalformat) && !isCompressed)
{
return error(GL_INVALID_ENUM);
}
@@ -3760,42 +3616,59 @@
{
switch(target)
{
+ case GL_TEXTURE_RECTANGLE_ARB:
+ if(isCompressed) // Rectangle textures cannot be compressed
+ {
+ return error(GL_INVALID_ENUM);
+ }
case GL_TEXTURE_2D:
- {
- es2::Texture2D *texture = context->getTexture2D();
- if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
{
- return error(GL_INVALID_OPERATION);
- }
+ if((width > es2::IMPLEMENTATION_MAX_TEXTURE_SIZE) ||
+ (height > es2::IMPLEMENTATION_MAX_TEXTURE_SIZE))
+ {
+ return error(GL_INVALID_VALUE);
+ }
- for(int level = 0; level < levels; ++level)
- {
- texture->setImage(context, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
- width = std::max(1, (width / 2));
- height = std::max(1, (height / 2));
+ es2::Texture2D *texture = context->getTexture2D(target);
+ if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ for(int level = 0; level < levels; level++)
+ {
+ texture->setImage(level, width, height, internalformat, GL_NONE, GL_NONE, context->getUnpackParameters(), nullptr);
+ width = std::max(1, (width / 2));
+ height = std::max(1, (height / 2));
+ }
+ texture->makeImmutable(levels);
}
- texture->makeImmutable(levels);
- }
break;
case GL_TEXTURE_CUBE_MAP:
- {
- es2::TextureCubeMap *texture = context->getTextureCubeMap();
- if(!texture || texture->name == 0 || texture->getImmutableFormat())
{
- return error(GL_INVALID_OPERATION);
- }
-
- for(int level = 0; level < levels; ++level)
- {
- for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)
+ if((width > es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE) ||
+ (height > es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE))
{
- texture->setImage(context, face, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
+ return error(GL_INVALID_VALUE);
}
- width = std::max(1, (width / 2));
- height = std::max(1, (height / 2));
+
+ es2::TextureCubeMap *texture = context->getTextureCubeMap();
+ if(!texture || texture->name == 0 || texture->getImmutableFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ for(int level = 0; level < levels; level++)
+ {
+ for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
+ {
+ texture->setImage(face, level, width, height, internalformat, GL_NONE, GL_NONE, context->getUnpackParameters(), nullptr);
+ }
+ width = std::max(1, (width / 2));
+ height = std::max(1, (height / 2));
+ }
+ texture->makeImmutable(levels);
}
- texture->makeImmutable(levels);
- }
break;
default:
return error(GL_INVALID_ENUM);
@@ -3813,8 +3686,7 @@
return error(GL_INVALID_VALUE);
}
- GLenum type;
- if(!GetStorageType(internalformat, type))
+ if(!IsSizedInternalFormat(internalformat) && !IsCompressed(internalformat, egl::getClientVersion()))
{
return error(GL_INVALID_ENUM);
}
@@ -3826,52 +3698,52 @@
switch(target)
{
case GL_TEXTURE_3D:
- {
- if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))
{
- return error(GL_INVALID_OPERATION);
- }
+ if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(std::max(width, height), depth)) + 1))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
- es2::Texture3D *texture = context->getTexture3D();
- if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
- {
- return error(GL_INVALID_OPERATION);
- }
+ es2::Texture3D *texture = context->getTexture3D();
+ if(!texture || texture->name == 0 || texture->getImmutableFormat() == GL_TRUE)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
- for(int level = 0; level < levels; ++level)
- {
- texture->setImage(context, level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
- width = std::max(1, (width / 2));
- height = std::max(1, (height / 2));
- depth = std::max(1, (depth / 2));
+ for(int level = 0; level < levels; level++)
+ {
+ texture->setImage(level, width, height, depth, internalformat, GL_NONE, GL_NONE, context->getUnpackParameters(), nullptr);
+ width = std::max(1, (width / 2));
+ height = std::max(1, (height / 2));
+ depth = std::max(1, (depth / 2));
+ }
+ texture->makeImmutable(levels);
}
- texture->makeImmutable(levels);
- }
break;
case GL_TEXTURE_2D_ARRAY:
- {
- if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
{
- return error(GL_INVALID_OPERATION);
- }
-
- es2::Texture3D *texture = context->getTexture2DArray();
- if(!texture || texture->name == 0 || texture->getImmutableFormat())
- {
- return error(GL_INVALID_OPERATION);
- }
-
- for(int level = 0; level < levels; ++level)
- {
- for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)
+ if(levels > es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || levels > (log2(std::max(width, height)) + 1))
{
- texture->setImage(context, level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), nullptr);
+ return error(GL_INVALID_OPERATION);
}
- width = std::max(1, (width / 2));
- height = std::max(1, (height / 2));
+
+ es2::Texture3D *texture = context->getTexture2DArray();
+ if(!texture || texture->name == 0 || texture->getImmutableFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ for(int level = 0; level < levels; level++)
+ {
+ for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
+ {
+ texture->setImage(level, width, height, depth, internalformat, GL_NONE, GL_NONE, context->getUnpackParameters(), nullptr);
+ }
+ width = std::max(1, (width / 2));
+ height = std::max(1, (height / 2));
+ }
+ texture->makeImmutable(levels);
}
- texture->makeImmutable(levels);
- }
break;
default:
return error(GL_INVALID_ENUM);
@@ -3894,7 +3766,13 @@
return;
}
- if(!IsColorRenderable(internalformat, egl::getClientVersion(), false) &&
+ // OpenGL ES 3.0, section 4.4.4: "An internal format is color-renderable if it is one of the formats
+ // from table 3.13 noted as color-renderable or if it is unsized format RGBA or RGB."
+ // Since we only use sized formats internally, replace them here (assuming type = GL_UNSIGNED_BYTE).
+ if(internalformat == GL_RGB) internalformat = GL_RGB8;
+ if(internalformat == GL_RGBA) internalformat = GL_RGBA8;
+
+ if(!IsColorRenderable(internalformat, egl::getClientVersion()) &&
!IsDepthRenderable(internalformat, egl::getClientVersion()) &&
!IsStencilRenderable(internalformat, egl::getClientVersion()))
{
@@ -3909,39 +3787,13 @@
return error(GL_INVALID_ENUM);
}
- // Integer types have no multisampling
GLint numMultisampleCounts = NUM_MULTISAMPLE_COUNTS;
- switch(internalformat)
+
+ // Integer types have no multisampling
+ GLenum type = GetColorComponentType(internalformat);
+ if(type != GL_UNSIGNED_NORMALIZED && type != GL_FLOAT)
{
- case GL_R8UI:
- case GL_R8I:
- case GL_R16UI:
- case GL_R16I:
- case GL_R32UI:
- case GL_R32I:
- case GL_RG8UI:
- case GL_RG8I:
- case GL_RG16UI:
- case GL_RG16I:
- case GL_RG32UI:
- case GL_RG32I:
- case GL_RGB8UI:
- case GL_RGB8I:
- case GL_RGB16UI:
- case GL_RGB16I:
- case GL_RGB32UI:
- case GL_RGB32I:
- case GL_RGBA8UI:
- case GL_RGBA8I:
- case GL_RGB10_A2UI:
- case GL_RGBA16UI:
- case GL_RGBA16I:
- case GL_RGBA32UI:
- case GL_RGBA32I:
numMultisampleCounts = 0;
- break;
- default:
- break;
}
switch(pname)
diff --git a/src/OpenGL/libGLESv2/main.cpp b/src/OpenGL/libGLESv2/main.cpp
index 81b1689..0924a75 100644
--- a/src/OpenGL/libGLESv2/main.cpp
+++ b/src/OpenGL/libGLESv2/main.cpp
@@ -12,18 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// main.cpp: DLL entry point and management of thread-local data.
+// main.cpp: DLLMain and management of thread-local data.
#include "main.h"
-#include "libGLESv2.hpp"
-#include "Framebuffer.h"
-#include "libEGL/main.h"
-#include "common/Surface.hpp"
-#include "Common/Thread.hpp"
-#include "Common/SharedLibrary.hpp"
-#include "common/debug.h"
-
#if !defined(_MSC_VER)
#define CONSTRUCTOR __attribute__((constructor))
#define DESTRUCTOR __attribute__((destructor))
@@ -147,1412 +139,3 @@
return context ? context->getClientVersion() : 0;
}
}
-
-namespace es2
-{
-void ActiveTexture(GLenum texture);
-void AttachShader(GLuint program, GLuint shader);
-void BeginQueryEXT(GLenum target, GLuint name);
-void BindAttribLocation(GLuint program, GLuint index, const GLchar* name);
-void BindBuffer(GLenum target, GLuint buffer);
-void BindFramebuffer(GLenum target, GLuint framebuffer);
-void BindRenderbuffer(GLenum target, GLuint renderbuffer);
-void BindTexture(GLenum target, GLuint texture);
-void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
-void BlendEquation(GLenum mode);
-void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
-void BlendFunc(GLenum sfactor, GLenum dfactor);
-void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
-void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
-void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
-GLenum CheckFramebufferStatus(GLenum target);
-void Clear(GLbitfield mask);
-void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
-void ClearDepthf(GLclampf depth);
-void ClearStencil(GLint s);
-void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
-void CompileShader(GLuint shader);
-void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
- GLint border, GLsizei imageSize, const GLvoid* data);
-void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const GLvoid* data);
-void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
-void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-GLuint CreateProgram(void);
-GLuint CreateShader(GLenum type);
-void CullFace(GLenum mode);
-void DeleteBuffers(GLsizei n, const GLuint* buffers);
-void DeleteFencesNV(GLsizei n, const GLuint* fences);
-void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
-void DeleteProgram(GLuint program);
-void DeleteQueriesEXT(GLsizei n, const GLuint *ids);
-void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
-void DeleteShader(GLuint shader);
-void DeleteTextures(GLsizei n, const GLuint* textures);
-void DepthFunc(GLenum func);
-void DepthMask(GLboolean flag);
-void DepthRangef(GLclampf zNear, GLclampf zFar);
-void DetachShader(GLuint program, GLuint shader);
-void Disable(GLenum cap);
-void DisableVertexAttribArray(GLuint index);
-void DrawArrays(GLenum mode, GLint first, GLsizei count);
-void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
-void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
-void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount);
-void VertexAttribDivisorEXT(GLuint index, GLuint divisor);
-void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
-void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount);
-void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
-void Enable(GLenum cap);
-void EnableVertexAttribArray(GLuint index);
-void EndQueryEXT(GLenum target);
-void FinishFenceNV(GLuint fence);
-void Finish(void);
-void Flush(void);
-void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
-void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-void FrontFace(GLenum mode);
-void GenBuffers(GLsizei n, GLuint* buffers);
-void GenerateMipmap(GLenum target);
-void GenFencesNV(GLsizei n, GLuint* fences);
-void GenFramebuffers(GLsizei n, GLuint* framebuffers);
-void GenQueriesEXT(GLsizei n, GLuint* ids);
-void GenRenderbuffers(GLsizei n, GLuint* renderbuffers);
-void GenTextures(GLsizei n, GLuint* textures);
-void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
-void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
-void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
-int GetAttribLocation(GLuint program, const GLchar* name);
-void GetBooleanv(GLenum pname, GLboolean* params);
-void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
-GLenum GetError(void);
-void GetFenceivNV(GLuint fence, GLenum pname, GLint *params);
-void GetFloatv(GLenum pname, GLfloat* params);
-void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
-GLenum GetGraphicsResetStatusEXT(void);
-void GetIntegerv(GLenum pname, GLint* params);
-void GetProgramiv(GLuint program, GLenum pname, GLint* params);
-void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
-void GetQueryivEXT(GLenum target, GLenum pname, GLint *params);
-void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params);
-void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
-void GetShaderiv(GLuint shader, GLenum pname, GLint* params);
-void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
-void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
-void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
-const GLubyte* GetString(GLenum name);
-void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
-void GetTexParameteriv(GLenum target, GLenum pname, GLint* params);
-void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
-void GetUniformfv(GLuint program, GLint location, GLfloat* params);
-void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params);
-void GetUniformiv(GLuint program, GLint location, GLint* params);
-int GetUniformLocation(GLuint program, const GLchar* name);
-void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
-void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
-void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
-void Hint(GLenum target, GLenum mode);
-GLboolean IsBuffer(GLuint buffer);
-GLboolean IsEnabled(GLenum cap);
-GLboolean IsFenceNV(GLuint fence);
-GLboolean IsFramebuffer(GLuint framebuffer);
-GLboolean IsProgram(GLuint program);
-GLboolean IsQueryEXT(GLuint name);
-GLboolean IsRenderbuffer(GLuint renderbuffer);
-GLboolean IsShader(GLuint shader);
-GLboolean IsTexture(GLuint texture);
-void LineWidth(GLfloat width);
-void LinkProgram(GLuint program);
-void PixelStorei(GLenum pname, GLint param);
-void PolygonOffset(GLfloat factor, GLfloat units);
-void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
-void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
-void ReleaseShaderCompiler(void);
-void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
-void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
-void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-void SampleCoverage(GLclampf value, GLboolean invert);
-void SetFenceNV(GLuint fence, GLenum condition);
-void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
-void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
-void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length);
-void StencilFunc(GLenum func, GLint ref, GLuint mask);
-void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
-void StencilMask(GLuint mask);
-void StencilMaskSeparate(GLenum face, GLuint mask);
-void StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
-void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-GLboolean TestFenceNV(GLuint fence);
-void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, const GLvoid* pixels);
-void TexParameterf(GLenum target, GLenum pname, GLfloat param);
-void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
-void TexParameteri(GLenum target, GLenum pname, GLint param);
-void TexParameteriv(GLenum target, GLenum pname, const GLint* params);
-void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid* pixels);
-void Uniform1f(GLint location, GLfloat x);
-void Uniform1fv(GLint location, GLsizei count, const GLfloat* v);
-void Uniform1i(GLint location, GLint x);
-void Uniform1iv(GLint location, GLsizei count, const GLint* v);
-void Uniform2f(GLint location, GLfloat x, GLfloat y);
-void Uniform2fv(GLint location, GLsizei count, const GLfloat* v);
-void Uniform2i(GLint location, GLint x, GLint y);
-void Uniform2iv(GLint location, GLsizei count, const GLint* v);
-void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
-void Uniform3fv(GLint location, GLsizei count, const GLfloat* v);
-void Uniform3i(GLint location, GLint x, GLint y, GLint z);
-void Uniform3iv(GLint location, GLsizei count, const GLint* v);
-void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-void Uniform4fv(GLint location, GLsizei count, const GLfloat* v);
-void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
-void Uniform4iv(GLint location, GLsizei count, const GLint* v);
-void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
-void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
-void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
-void UseProgram(GLuint program);
-void ValidateProgram(GLuint program);
-void VertexAttrib1f(GLuint index, GLfloat x);
-void VertexAttrib1fv(GLuint index, const GLfloat* values);
-void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
-void VertexAttrib2fv(GLuint index, const GLfloat* values);
-void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
-void VertexAttrib3fv(GLuint index, const GLfloat* values);
-void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-void VertexAttrib4fv(GLuint index, const GLfloat* values);
-GL_APICALL void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
-GL_APICALL void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
-GL_APICALL void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
-GL_APICALL void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
-GL_APICALL void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum format, GLenum type, const GLvoid* pixels);
-GL_APICALL void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
-GL_APICALL void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-GL_APICALL void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
-GL_APICALL void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
-GL_APICALL void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
-GL_APICALL void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
-GL_APICALL void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
-GL_APICALL GLboolean IsRenderbufferOES(GLuint renderbuffer);
-GL_APICALL void BindRenderbufferOES(GLenum target, GLuint renderbuffer);
-GL_APICALL void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);
-GL_APICALL void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);
-GL_APICALL void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-GL_APICALL void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);
-GL_APICALL GLboolean IsFramebufferOES(GLuint framebuffer);
-GL_APICALL void BindFramebufferOES(GLenum target, GLuint framebuffer);
-GL_APICALL void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);
-GL_APICALL void GenFramebuffersOES(GLsizei n, GLuint* framebuffers);
-GL_APICALL GLenum CheckFramebufferStatusOES(GLenum target);
-GL_APICALL void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
-GL_APICALL void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-GL_APICALL void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);
-GL_APICALL void GenerateMipmapOES(GLenum target);
-GL_APICALL void DrawBuffersEXT(GLsizei n, const GLenum *bufs);
-}
-
-extern "C"
-{
-GL_APICALL void GL_APIENTRY glActiveTexture(GLenum texture)
-{
- return es2::ActiveTexture(texture);
-}
-
-GL_APICALL void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
-{
- return es2::AttachShader(program, shader);
-}
-
-GL_APICALL void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
-{
- return es2::BeginQueryEXT(target, name);
-}
-
-GL_APICALL void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
-{
- return es2::BindAttribLocation(program, index, name);
-}
-
-GL_APICALL void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
-{
- return es2::BindBuffer(target, buffer);
-}
-
-GL_APICALL void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
-{
- return es2::BindFramebuffer(target, framebuffer);
-}
-
-GL_APICALL void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)
-{
- return es2::BindFramebuffer(target, framebuffer);
-}
-
-GL_APICALL void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
-{
- return es2::BindRenderbuffer(target, renderbuffer);
-}
-
-GL_APICALL void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
-{
- return es2::BindRenderbuffer(target, renderbuffer);
-}
-
-GL_APICALL void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
-{
- return es2::BindTexture(target, texture);
-}
-
-GL_APICALL void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-{
- return es2::BlendColor(red, green, blue, alpha);
-}
-
-GL_APICALL void GL_APIENTRY glBlendEquation(GLenum mode)
-{
- return es2::BlendEquation(mode);
-}
-
-GL_APICALL void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
-{
- return es2::BlendEquationSeparate(modeRGB, modeAlpha);
-}
-
-GL_APICALL void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
-{
- return es2::BlendFunc(sfactor, dfactor);
-}
-
-GL_APICALL void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-{
- return es2::BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-
-GL_APICALL void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
-{
- return es2::BufferData(target, size, data, usage);
-}
-
-GL_APICALL void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
-{
- return es2::BufferSubData(target, offset, size, data);
-}
-
-GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
-{
- return es2::CheckFramebufferStatus(target);
-}
-
-GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)
-{
- return es2::CheckFramebufferStatus(target);
-}
-
-GL_APICALL void GL_APIENTRY glClear(GLbitfield mask)
-{
- return es2::Clear(mask);
-}
-
-GL_APICALL void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-{
- return es2::ClearColor(red, green, blue, alpha);
-}
-
-GL_APICALL void GL_APIENTRY glClearDepthf(GLclampf depth)
-{
- return es2::ClearDepthf(depth);
-}
-
-GL_APICALL void GL_APIENTRY glClearStencil(GLint s)
-{
- return es2::ClearStencil(s);
-}
-
-GL_APICALL void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
-{
- return es2::ColorMask(red, green, blue, alpha);
-}
-
-GL_APICALL void GL_APIENTRY glCompileShader(GLuint shader)
-{
- return es2::CompileShader(shader);
-}
-
-GL_APICALL void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
- GLint border, GLsizei imageSize, const GLvoid* data)
-{
- return es2::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
-}
-
-GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const GLvoid* data)
-{
- return es2::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
-}
-
-GL_APICALL void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
-{
- return es2::CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
-}
-
-GL_APICALL void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-{
- return es2::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
-}
-
-GL_APICALL GLuint GL_APIENTRY glCreateProgram(void)
-{
- return es2::CreateProgram();
-}
-
-GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type)
-{
- return es2::CreateShader(type);
-}
-
-GL_APICALL void GL_APIENTRY glCullFace(GLenum mode)
-{
- return es2::CullFace(mode);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
-{
- return es2::DeleteBuffers(n, buffers);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
-{
- return es2::DeleteFencesNV(n, fences);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
-{
- return es2::DeleteFramebuffers(n, framebuffers);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
-{
- return es2::DeleteFramebuffers(n, framebuffers);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program)
-{
- return es2::DeleteProgram(program);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
-{
- return es2::DeleteQueriesEXT(n, ids);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
-{
- return es2::DeleteRenderbuffers(n, renderbuffers);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
-{
- return es2::DeleteRenderbuffers(n, renderbuffers);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader)
-{
- return es2::DeleteShader(shader);
-}
-
-GL_APICALL void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
-{
- return es2::DeleteTextures(n, textures);
-}
-
-GL_APICALL void GL_APIENTRY glDepthFunc(GLenum func)
-{
- return es2::DepthFunc(func);
-}
-
-GL_APICALL void GL_APIENTRY glDepthMask(GLboolean flag)
-{
- return es2::DepthMask(flag);
-}
-
-GL_APICALL void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
-{
- return es2::DepthRangef(zNear, zFar);
-}
-
-GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
-{
- return es2::DetachShader(program, shader);
-}
-
-GL_APICALL void GL_APIENTRY glDisable(GLenum cap)
-{
- return es2::Disable(cap);
-}
-
-GL_APICALL void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
-{
- return es2::DisableVertexAttribArray(index);
-}
-
-GL_APICALL void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
-{
- return es2::DrawArrays(mode, first, count);
-}
-
-GL_APICALL void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
-{
- return es2::DrawElements(mode, count, type, indices);
-}
-
-GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
-{
- return es2::DrawArraysInstancedEXT(mode, first, count, instanceCount);
-}
-
-GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
-{
- return es2::DrawElementsInstancedEXT(mode, count, type, indices, instanceCount);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT(GLuint index, GLuint divisor)
-{
- return es2::VertexAttribDivisorEXT(index, divisor);
-}
-
-GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
-{
- return es2::DrawArraysInstancedANGLE(mode, first, count, instanceCount);
-}
-
-GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
-{
- return es2::DrawElementsInstancedANGLE(mode, count, type, indices, instanceCount);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
-{
- return es2::VertexAttribDivisorANGLE(index, divisor);
-}
-
-GL_APICALL void GL_APIENTRY glEnable(GLenum cap)
-{
- return es2::Enable(cap);
-}
-
-GL_APICALL void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
-{
- return es2::EnableVertexAttribArray(index);
-}
-
-GL_APICALL void GL_APIENTRY glEndQueryEXT(GLenum target)
-{
- return es2::EndQueryEXT(target);
-}
-
-GL_APICALL void GL_APIENTRY glFinishFenceNV(GLuint fence)
-{
- return es2::FinishFenceNV(fence);
-}
-
-GL_APICALL void GL_APIENTRY glFinish(void)
-{
- return es2::Finish();
-}
-
-GL_APICALL void GL_APIENTRY glFlush(void)
-{
- return es2::Flush();
-}
-
-GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
-{
- return es2::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
-}
-
-GL_APICALL void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
-{
- return es2::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
-}
-
-GL_APICALL void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
-{
- return es2::FramebufferTexture2D(target, attachment, textarget, texture, level);
-}
-
-GL_APICALL void GL_APIENTRY glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
-{
- return es2::FramebufferTexture2D(target, attachment, textarget, texture, level);
-}
-
-GL_APICALL void GL_APIENTRY glFrontFace(GLenum mode)
-{
- return es2::FrontFace(mode);
-}
-
-GL_APICALL void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
-{
- return es2::GenBuffers(n, buffers);
-}
-
-GL_APICALL void GL_APIENTRY glGenerateMipmap(GLenum target)
-{
- return es2::GenerateMipmap(target);
-}
-
-GL_APICALL void GL_APIENTRY glGenerateMipmapOES(GLenum target)
-{
- return es2::GenerateMipmap(target);
-}
-
-GL_APICALL void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
-{
- return es2::GenFencesNV(n, fences);
-}
-
-GL_APICALL void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
-{
- return es2::GenFramebuffers(n, framebuffers);
-}
-
-GL_APICALL void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint* framebuffers)
-{
- return es2::GenFramebuffers(n, framebuffers);
-}
-
-GL_APICALL void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
-{
- return es2::GenQueriesEXT(n, ids);
-}
-
-GL_APICALL void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
-{
- return es2::GenRenderbuffers(n, renderbuffers);
-}
-
-GL_APICALL void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
-{
- return es2::GenRenderbuffers(n, renderbuffers);
-}
-
-GL_APICALL void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
-{
- return es2::GenTextures(n, textures);
-}
-
-GL_APICALL void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
-{
- return es2::GetActiveAttrib(program, index, bufsize, length, size, type, name);
-}
-
-GL_APICALL void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
-{
- return es2::GetActiveUniform(program, index, bufsize, length, size, type, name);
-}
-
-GL_APICALL void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
-{
- return es2::GetAttachedShaders(program, maxcount, count, shaders);
-}
-
-GL_APICALL int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
-{
- return es2::GetAttribLocation(program, name);
-}
-
-GL_APICALL void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
-{
- return es2::GetBooleanv(pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
-{
- return es2::GetBufferParameteriv(target, pname, params);
-}
-
-GL_APICALL GLenum GL_APIENTRY glGetError(void)
-{
- return es2::GetError();
-}
-
-GL_APICALL void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
-{
- return es2::GetFenceivNV(fence, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
-{
- return es2::GetFloatv(pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
-{
- return es2::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
-{
- return es2::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
-}
-
-GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
-{
- return es2::GetGraphicsResetStatusEXT();
-}
-
-GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
-{
- return es2::GetIntegerv(pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
-{
- return es2::GetProgramiv(program, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
-{
- return es2::GetProgramInfoLog(program, bufsize, length, infolog);
-}
-
-GL_APICALL void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
-{
- return es2::GetQueryivEXT(target, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
-{
- return es2::GetQueryObjectuivEXT(name, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
-{
- return es2::GetRenderbufferParameteriv(target, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
-{
- return es2::GetRenderbufferParameteriv(target, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
-{
- return es2::GetShaderiv(shader, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
-{
- return es2::GetShaderInfoLog(shader, bufsize, length, infolog);
-}
-
-GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
-{
- return es2::GetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
-}
-
-GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
-{
- return es2::GetShaderSource(shader, bufsize, length, source);
-}
-
-GL_APICALL const GLubyte* GL_APIENTRY glGetString(GLenum name)
-{
- return es2::GetString(name);
-}
-
-GL_APICALL void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
-{
- return es2::GetTexParameterfv(target, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
-{
- return es2::GetTexParameteriv(target, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
-{
- return es2::GetnUniformfvEXT(program, location, bufSize, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
-{
- return es2::GetUniformfv(program, location, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
-{
- return es2::GetnUniformivEXT(program, location, bufSize, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
-{
- return es2::GetUniformiv(program, location, params);
-}
-
-GL_APICALL int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
-{
- return es2::GetUniformLocation(program, name);
-}
-
-GL_APICALL void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
-{
- return es2::GetVertexAttribfv(index, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
-{
- return es2::GetVertexAttribiv(index, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
-{
- return es2::GetVertexAttribPointerv(index, pname, pointer);
-}
-
-GL_APICALL void GL_APIENTRY glHint(GLenum target, GLenum mode)
-{
- return es2::Hint(target, mode);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
-{
- return es2::IsBuffer(buffer);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
-{
- return es2::IsEnabled(cap);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
-{
- return es2::IsFenceNV(fence);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
-{
- return es2::IsFramebuffer(framebuffer);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)
-{
- return es2::IsFramebuffer(framebuffer);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsProgram(GLuint program)
-{
- return es2::IsProgram(program);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT(GLuint name)
-{
- return es2::IsQueryEXT(name);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
-{
- return es2::IsRenderbuffer(renderbuffer);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)
-{
- return es2::IsRenderbuffer(renderbuffer);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsShader(GLuint shader)
-{
- return es2::IsShader(shader);
-}
-
-GL_APICALL GLboolean GL_APIENTRY glIsTexture(GLuint texture)
-{
- return es2::IsTexture(texture);
-}
-
-GL_APICALL void GL_APIENTRY glLineWidth(GLfloat width)
-{
- return es2::LineWidth(width);
-}
-
-GL_APICALL void GL_APIENTRY glLinkProgram(GLuint program)
-{
- return es2::LinkProgram(program);
-}
-
-GL_APICALL void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
-{
- return es2::PixelStorei(pname, param);
-}
-
-GL_APICALL void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
-{
- return es2::PolygonOffset(factor, units);
-}
-
-GL_APICALL void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
-{
- return es2::ReadnPixelsEXT(x, y, width, height, format, type, bufSize, data);
-}
-
-GL_APICALL void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
-{
- return es2::ReadPixels(x, y, width, height, format, type, pixels);
-}
-
-GL_APICALL void GL_APIENTRY glReleaseShaderCompiler(void)
-{
- return es2::ReleaseShaderCompiler();
-}
-
-GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
-{
- return es2::RenderbufferStorageMultisample(target, samples, internalformat, width, height);
-}
-
-GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
-{
- return es2::RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
-}
-
-GL_APICALL void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-{
- return es2::RenderbufferStorage(target, internalformat, width, height);
-}
-
-GL_APICALL void GL_APIENTRY glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-{
- return es2::RenderbufferStorage(target, internalformat, width, height);
-}
-
-GL_APICALL void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
-{
- return es2::SampleCoverage(value, invert);
-}
-
-GL_APICALL void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
-{
- return es2::SetFenceNV(fence, condition);
-}
-
-GL_APICALL void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
-{
- return es2::Scissor(x, y, width, height);
-}
-
-GL_APICALL void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
-{
- return es2::ShaderBinary(n, shaders, binaryformat, binary, length);
-}
-
-GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
-{
- return es2::ShaderSource(shader, count, string, length);
-}
-
-GL_APICALL void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
-{
- return es2::StencilFunc(func, ref, mask);
-}
-
-GL_APICALL void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
-{
- return es2::StencilFuncSeparate(face, func, ref, mask);
-}
-
-GL_APICALL void GL_APIENTRY glStencilMask(GLuint mask)
-{
- return es2::StencilMask(mask);
-}
-
-GL_APICALL void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
-{
- return es2::StencilMaskSeparate(face, mask);
-}
-
-GL_APICALL void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
-{
- return es2::StencilOp(fail, zfail, zpass);
-}
-
-GL_APICALL void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
-{
- return es2::StencilOpSeparate(face, fail, zfail, zpass);
-}
-
-GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
-{
- return es2::TestFenceNV(fence);
-}
-
-GL_APICALL void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-{
- return es2::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
-}
-
-GL_APICALL void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
-{
- return es2::TexParameterf(target, pname, param);
-}
-
-GL_APICALL void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
-{
- return es2::TexParameterfv(target, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
-{
- return es2::TexParameteri(target, pname, param);
-}
-
-GL_APICALL void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
-{
- return es2::TexParameteriv(target, pname, params);
-}
-
-GL_APICALL void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid* pixels)
-{
- return es2::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-GL_APICALL void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
-{
- return es2::Uniform1f(location, x);
-}
-
-GL_APICALL void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
-{
- return es2::Uniform1fv(location, count, v);
-}
-
-GL_APICALL void GL_APIENTRY glUniform1i(GLint location, GLint x)
-{
- return es2::Uniform1i(location, x);
-}
-
-GL_APICALL void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
-{
- return es2::Uniform1iv(location, count, v);
-}
-
-GL_APICALL void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
-{
- return es2::Uniform2f(location, x, y);
-}
-
-GL_APICALL void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
-{
- return es2::Uniform2fv(location, count, v);
-}
-
-GL_APICALL void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
-{
- return es2::Uniform2i(location, x, y);
-}
-
-GL_APICALL void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
-{
- return es2::Uniform2iv(location, count, v);
-}
-
-GL_APICALL void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
-{
- return es2::Uniform3f(location, x, y, z);
-}
-
-GL_APICALL void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
-{
- return es2::Uniform3fv(location, count, v);
-}
-
-GL_APICALL void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
-{
- return es2::Uniform3i(location, x, y, z);
-}
-
-GL_APICALL void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
-{
- return es2::Uniform3iv(location, count, v);
-}
-
-GL_APICALL void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
- return es2::Uniform4f(location, x, y, z, w);
-}
-
-GL_APICALL void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
-{
- return es2::Uniform4fv(location, count, v);
-}
-
-GL_APICALL void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
-{
- return es2::Uniform4i(location, x, y, z, w);
-}
-
-GL_APICALL void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
-{
- return es2::Uniform4iv(location, count, v);
-}
-
-GL_APICALL void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
- return es2::UniformMatrix2fv(location, count, transpose, value);
-}
-
-GL_APICALL void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
- return es2::UniformMatrix3fv(location, count, transpose, value);
-}
-
-GL_APICALL void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
- return es2::UniformMatrix4fv(location, count, transpose, value);
-}
-
-GL_APICALL void GL_APIENTRY glUseProgram(GLuint program)
-{
- return es2::UseProgram(program);
-}
-
-GL_APICALL void GL_APIENTRY glValidateProgram(GLuint program)
-{
- return es2::ValidateProgram(program);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
-{
- return es2::VertexAttrib1f(index, x);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
-{
- return es2::VertexAttrib1fv(index, values);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
-{
- return es2::VertexAttrib2f(index, x, y);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
-{
- return es2::VertexAttrib2fv(index, values);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
-{
- return es2::VertexAttrib3f(index, x, y, z);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
-{
- return es2::VertexAttrib3fv(index, values);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
- return es2::VertexAttrib4f(index, x, y, z, w);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
-{
- return es2::VertexAttrib4fv(index, values);
-}
-
-GL_APICALL void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
-{
- return es2::VertexAttribPointer(index, size, type, normalized, stride, ptr);
-}
-
-GL_APICALL void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
-{
- return es2::Viewport(x, y, width, height);
-}
-
-GL_APICALL void GL_APIENTRY glBlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
-{
- return es2::BlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-}
-
-GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- return es2::BlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-}
-
-GL_APICALL void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-{
- return es2::TexImage3DOES(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
-GL_APICALL void GL_APIENTRY glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
-{
- return es2::TexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
-}
-
-GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-{
- return es2::CopyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);
-}
-
-GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
-{
- return es2::CompressedTexImage3DOES(target, level,internalformat, width, height, depth, border, imageSize, data);
-}
-
-GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
-{
- return es2::CompressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
-}
-
-GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
-{
- return es2::FramebufferTexture3DOES(target, attachment, textarget, texture, level, zoffset);
-}
-
-GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
-{
- return es2::EGLImageTargetTexture2DOES(target, image);
-}
-
-GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
-{
- return es2::EGLImageTargetRenderbufferStorageOES(target, image);
-}
-
-GL_APICALL void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
-{
- return es2::DrawBuffersEXT(n, bufs);
-}
-
-void GL_APIENTRY Register(const char *licenseKey)
-{
- // Nothing to do, SwiftShader is open-source
-}
-}
-
-egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, int clientVersion, const egl::Config *config);
-extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname);
-egl::Image *createBackBuffer(int width, int height, sw::Format format, int multiSampleDepth);
-egl::Image *createDepthStencil(int width, int height, sw::Format format, int multiSampleDepth);
-sw::FrameBuffer *createFrameBuffer(void *nativeDisplay, EGLNativeWindowType window, int width, int height);
-
-LibGLESv2exports::LibGLESv2exports()
-{
- this->glActiveTexture = es2::ActiveTexture;
- this->glAttachShader = es2::AttachShader;
- this->glBeginQueryEXT = es2::BeginQueryEXT;
- this->glBindAttribLocation = es2::BindAttribLocation;
- this->glBindBuffer = es2::BindBuffer;
- this->glBindFramebuffer = es2::BindFramebuffer;
- this->glBindRenderbuffer = es2::BindRenderbuffer;
- this->glBindTexture = es2::BindTexture;
- this->glBlendColor = es2::BlendColor;
- this->glBlendEquation = es2::BlendEquation;
- this->glBlendEquationSeparate = es2::BlendEquationSeparate;
- this->glBlendFunc = es2::BlendFunc;
- this->glBlendFuncSeparate = es2::BlendFuncSeparate;
- this->glBufferData = es2::BufferData;
- this->glBufferSubData = es2::BufferSubData;
- this->glCheckFramebufferStatus = es2::CheckFramebufferStatus;
- this->glClear = es2::Clear;
- this->glClearColor = es2::ClearColor;
- this->glClearDepthf = es2::ClearDepthf;
- this->glClearStencil = es2::ClearStencil;
- this->glColorMask = es2::ColorMask;
- this->glCompileShader = es2::CompileShader;
- this->glCompressedTexImage2D = es2::CompressedTexImage2D;
- this->glCompressedTexSubImage2D = es2::CompressedTexSubImage2D;
- this->glCopyTexImage2D = es2::CopyTexImage2D;
- this->glCopyTexSubImage2D = es2::CopyTexSubImage2D;
- this->glCreateProgram = es2::CreateProgram;
- this->glCreateShader = es2::CreateShader;
- this->glCullFace = es2::CullFace;
- this->glDeleteBuffers = es2::DeleteBuffers;
- this->glDeleteFencesNV = es2::DeleteFencesNV;
- this->glDeleteFramebuffers = es2::DeleteFramebuffers;
- this->glDeleteProgram = es2::DeleteProgram;
- this->glDeleteQueriesEXT = es2::DeleteQueriesEXT;
- this->glDeleteRenderbuffers = es2::DeleteRenderbuffers;
- this->glDeleteShader = es2::DeleteShader;
- this->glDeleteTextures = es2::DeleteTextures;
- this->glDepthFunc = es2::DepthFunc;
- this->glDepthMask = es2::DepthMask;
- this->glDepthRangef = es2::DepthRangef;
- this->glDetachShader = es2::DetachShader;
- this->glDisable = es2::Disable;
- this->glDisableVertexAttribArray = es2::DisableVertexAttribArray;
- this->glDrawArrays = es2::DrawArrays;
- this->glDrawElements = es2::DrawElements;
- this->glDrawArraysInstancedEXT = es2::DrawArraysInstancedEXT;
- this->glDrawElementsInstancedEXT = es2::DrawElementsInstancedEXT;
- this->glVertexAttribDivisorEXT = es2::VertexAttribDivisorEXT;
- this->glDrawArraysInstancedANGLE = es2::DrawArraysInstancedANGLE;
- this->glDrawElementsInstancedANGLE = es2::DrawElementsInstancedANGLE;
- this->glVertexAttribDivisorANGLE = es2::VertexAttribDivisorANGLE;
- this->glEnable = es2::Enable;
- this->glEnableVertexAttribArray = es2::EnableVertexAttribArray;
- this->glEndQueryEXT = es2::EndQueryEXT;
- this->glFinishFenceNV = es2::FinishFenceNV;
- this->glFinish = es2::Finish;
- this->glFlush = es2::Flush;
- this->glFramebufferRenderbuffer = es2::FramebufferRenderbuffer;
- this->glFramebufferTexture2D = es2::FramebufferTexture2D;
- this->glFrontFace = es2::FrontFace;
- this->glGenBuffers = es2::GenBuffers;
- this->glGenerateMipmap = es2::GenerateMipmap;
- this->glGenFencesNV = es2::GenFencesNV;
- this->glGenFramebuffers = es2::GenFramebuffers;
- this->glGenQueriesEXT = es2::GenQueriesEXT;
- this->glGenRenderbuffers = es2::GenRenderbuffers;
- this->glGenTextures = es2::GenTextures;
- this->glGetActiveAttrib = es2::GetActiveAttrib;
- this->glGetActiveUniform = es2::GetActiveUniform;
- this->glGetAttachedShaders = es2::GetAttachedShaders;
- this->glGetAttribLocation = es2::GetAttribLocation;
- this->glGetBooleanv = es2::GetBooleanv;
- this->glGetBufferParameteriv = es2::GetBufferParameteriv;
- this->glGetError = es2::GetError;
- this->glGetFenceivNV = es2::GetFenceivNV;
- this->glGetFloatv = es2::GetFloatv;
- this->glGetFramebufferAttachmentParameteriv = es2::GetFramebufferAttachmentParameteriv;
- this->glGetGraphicsResetStatusEXT = es2::GetGraphicsResetStatusEXT;
- this->glGetIntegerv = es2::GetIntegerv;
- this->glGetProgramiv = es2::GetProgramiv;
- this->glGetProgramInfoLog = es2::GetProgramInfoLog;
- this->glGetQueryivEXT = es2::GetQueryivEXT;
- this->glGetQueryObjectuivEXT = es2::GetQueryObjectuivEXT;
- this->glGetRenderbufferParameteriv = es2::GetRenderbufferParameteriv;
- this->glGetShaderiv = es2::GetShaderiv;
- this->glGetShaderInfoLog = es2::GetShaderInfoLog;
- this->glGetShaderPrecisionFormat = es2::GetShaderPrecisionFormat;
- this->glGetShaderSource = es2::GetShaderSource;
- this->glGetString = es2::GetString;
- this->glGetTexParameterfv = es2::GetTexParameterfv;
- this->glGetTexParameteriv = es2::GetTexParameteriv;
- this->glGetnUniformfvEXT = es2::GetnUniformfvEXT;
- this->glGetUniformfv = es2::GetUniformfv;
- this->glGetnUniformivEXT = es2::GetnUniformivEXT;
- this->glGetUniformiv = es2::GetUniformiv;
- this->glGetUniformLocation = es2::GetUniformLocation;
- this->glGetVertexAttribfv = es2::GetVertexAttribfv;
- this->glGetVertexAttribiv = es2::GetVertexAttribiv;
- this->glGetVertexAttribPointerv = es2::GetVertexAttribPointerv;
- this->glHint = es2::Hint;
- this->glIsBuffer = es2::IsBuffer;
- this->glIsEnabled = es2::IsEnabled;
- this->glIsFenceNV = es2::IsFenceNV;
- this->glIsFramebuffer = es2::IsFramebuffer;
- this->glIsProgram = es2::IsProgram;
- this->glIsQueryEXT = es2::IsQueryEXT;
- this->glIsRenderbuffer = es2::IsRenderbuffer;
- this->glIsShader = es2::IsShader;
- this->glIsTexture = es2::IsTexture;
- this->glLineWidth = es2::LineWidth;
- this->glLinkProgram = es2::LinkProgram;
- this->glPixelStorei = es2::PixelStorei;
- this->glPolygonOffset = es2::PolygonOffset;
- this->glReadnPixelsEXT = es2::ReadnPixelsEXT;
- this->glReadPixels = es2::ReadPixels;
- this->glReleaseShaderCompiler = es2::ReleaseShaderCompiler;
- this->glRenderbufferStorageMultisample = es2::RenderbufferStorageMultisample;
- this->glRenderbufferStorageMultisampleANGLE = es2::RenderbufferStorageMultisampleANGLE;
- this->glRenderbufferStorage = es2::RenderbufferStorage;
- this->glSampleCoverage = es2::SampleCoverage;
- this->glSetFenceNV = es2::SetFenceNV;
- this->glScissor = es2::Scissor;
- this->glShaderBinary = es2::ShaderBinary;
- this->glShaderSource = es2::ShaderSource;
- this->glStencilFunc = es2::StencilFunc;
- this->glStencilFuncSeparate = es2::StencilFuncSeparate;
- this->glStencilMask = es2::StencilMask;
- this->glStencilMaskSeparate = es2::StencilMaskSeparate;
- this->glStencilOp = es2::StencilOp;
- this->glStencilOpSeparate = es2::StencilOpSeparate;
- this->glTestFenceNV = es2::TestFenceNV;
- this->glTexImage2D = es2::TexImage2D;
- this->glTexParameterf = es2::TexParameterf;
- this->glTexParameterfv = es2::TexParameterfv;
- this->glTexParameteri = es2::TexParameteri;
- this->glTexParameteriv = es2::TexParameteriv;
- this->glTexSubImage2D = es2::TexSubImage2D;
- this->glUniform1f = es2::Uniform1f;
- this->glUniform1fv = es2::Uniform1fv;
- this->glUniform1i = es2::Uniform1i;
- this->glUniform1iv = es2::Uniform1iv;
- this->glUniform2f = es2::Uniform2f;
- this->glUniform2fv = es2::Uniform2fv;
- this->glUniform2i = es2::Uniform2i;
- this->glUniform2iv = es2::Uniform2iv;
- this->glUniform3f = es2::Uniform3f;
- this->glUniform3fv = es2::Uniform3fv;
- this->glUniform3i = es2::Uniform3i;
- this->glUniform3iv = es2::Uniform3iv;
- this->glUniform4f = es2::Uniform4f;
- this->glUniform4fv = es2::Uniform4fv;
- this->glUniform4i = es2::Uniform4i;
- this->glUniform4iv = es2::Uniform4iv;
- this->glUniformMatrix2fv = es2::UniformMatrix2fv;
- this->glUniformMatrix3fv = es2::UniformMatrix3fv;
- this->glUniformMatrix4fv = es2::UniformMatrix4fv;
- this->glUseProgram = es2::UseProgram;
- this->glValidateProgram = es2::ValidateProgram;
- this->glVertexAttrib1f = es2::VertexAttrib1f;
- this->glVertexAttrib1fv = es2::VertexAttrib1fv;
- this->glVertexAttrib2f = es2::VertexAttrib2f;
- this->glVertexAttrib2fv = es2::VertexAttrib2fv;
- this->glVertexAttrib3f = es2::VertexAttrib3f;
- this->glVertexAttrib3fv = es2::VertexAttrib3fv;
- this->glVertexAttrib4f = es2::VertexAttrib4f;
- this->glVertexAttrib4fv = es2::VertexAttrib4fv;
- this->glVertexAttribPointer = es2::VertexAttribPointer;
- this->glViewport = es2::Viewport;
- this->glBlitFramebufferNV = es2::BlitFramebufferNV;
- this->glBlitFramebufferANGLE = es2::BlitFramebufferANGLE;
- this->glTexImage3DOES = es2::TexImage3DOES;
- this->glTexSubImage3DOES = es2::TexSubImage3DOES;
- this->glCopyTexSubImage3DOES = es2::CopyTexSubImage3DOES;
- this->glCompressedTexImage3DOES = es2::CompressedTexImage3DOES;
- this->glCompressedTexSubImage3DOES = es2::CompressedTexSubImage3DOES;
- this->glFramebufferTexture3DOES = es2::FramebufferTexture3DOES;
- this->glEGLImageTargetTexture2DOES = es2::EGLImageTargetTexture2DOES;
- this->glEGLImageTargetRenderbufferStorageOES = es2::EGLImageTargetRenderbufferStorageOES;
- this->glIsRenderbufferOES = es2::IsRenderbufferOES;
- this->glBindRenderbufferOES = es2::BindRenderbufferOES;
- this->glDeleteRenderbuffersOES = es2::DeleteRenderbuffersOES;
- this->glGenRenderbuffersOES = es2::GenRenderbuffersOES;
- this->glRenderbufferStorageOES = es2::RenderbufferStorageOES;
- this->glGetRenderbufferParameterivOES = es2::GetRenderbufferParameterivOES;
- this->glIsFramebufferOES = es2::IsFramebufferOES;
- this->glBindFramebufferOES = es2::BindFramebufferOES;
- this->glDeleteFramebuffersOES = es2::DeleteFramebuffersOES;
- this->glGenFramebuffersOES = es2::GenFramebuffersOES;
- this->glCheckFramebufferStatusOES = es2::CheckFramebufferStatusOES;
- this->glFramebufferRenderbufferOES = es2::FramebufferRenderbufferOES;
- this->glFramebufferTexture2DOES = es2::FramebufferTexture2DOES;
- this->glGetFramebufferAttachmentParameterivOES = es2::GetFramebufferAttachmentParameterivOES;
- this->glGenerateMipmapOES = es2::GenerateMipmapOES;
- this->glDrawBuffersEXT = es2::DrawBuffersEXT;
-
- this->es2CreateContext = ::es2CreateContext;
- this->es2GetProcAddress = ::es2GetProcAddress;
- this->createBackBuffer = ::createBackBuffer;
- this->createDepthStencil = ::createDepthStencil;
- this->createFrameBuffer = ::createFrameBuffer;
-}
-
-extern "C" GL_APICALL LibGLESv2exports *libGLESv2_swiftshader()
-{
- static LibGLESv2exports libGLESv2;
- return &libGLESv2;
-}
-
-LibEGL libEGL;
-LibGLES_CM libGLES_CM;
\ No newline at end of file
diff --git a/src/OpenGL/libGLESv2/mathutil.h b/src/OpenGL/libGLESv2/mathutil.h
index 3c820a1..1b0280e 100644
--- a/src/OpenGL/libGLESv2/mathutil.h
+++ b/src/OpenGL/libGLESv2/mathutil.h
@@ -90,6 +90,11 @@
return static_cast<int>(roundf(x));
}
+
+inline int convert_float_fixed(float x)
+{
+ return convert_float_int(static_cast<float>(0x7FFFFFFF) * x);
+}
}
#endif // LIBGLESV2_MATHUTIL_H_
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp
index 4257b69..facc550 100644
--- a/src/OpenGL/libGLESv2/utilities.cpp
+++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -20,6 +20,7 @@
#include "main.h"
#include "mathutil.h"
#include "Context.h"
+#include "Shader.h"
#include "common/debug.h"
#include <limits>
@@ -28,153 +29,6 @@
namespace es2
{
- // ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
- // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
- // format and type combinations.
-
- typedef std::pair<GLenum, GLenum> FormatTypePair;
- typedef std::pair<FormatTypePair, GLenum> FormatPair;
- typedef std::map<FormatTypePair, GLenum> 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)
- {
- map->insert(FormatPair(FormatTypePair(format, type), internalFormat));
- }
-
- FormatMap BuildFormatMap()
- {
- static const GLenum GL_BGRA4_ANGLEX = 0x6ABC;
- static const GLenum GL_BGR5_A1_ANGLEX = 0x6ABD;
-
- FormatMap map;
-
- // | Format | Type | Internal format |
- InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);
- InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);
- InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);
- InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);
- InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);
- InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);
- InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);
- InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);
-
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);
-
- InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);
- InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);
- InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);
- InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);
- InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);
- InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);
- InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);
- InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);
-
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);
-
- InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);
- InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);
- InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);
- InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);
- InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);
-
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);
-
- InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);
- InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);
- InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);
- InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);
- InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);
-
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);
-
- InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);
- InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);
- InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);
- InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);
- InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);
- InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);
- InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);
- InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);
- InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);
- InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);
- InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);
- InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);
-
- InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);
- InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);
- InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);
-
- InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);
- InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);
-
- InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
- InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
- InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
- InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
-
- InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);
- InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);
- InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);
-
- InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);
-
- InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);
- InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);
-
- return map;
- }
-
- GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
- {
- switch(internalFormat)
- {
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_RED:
- case GL_RG:
- case GL_RGB:
- case GL_RGBA:
- case GL_RED_INTEGER:
- case GL_RG_INTEGER:
- case GL_RGB_INTEGER:
- case GL_RGBA_INTEGER:
- case GL_BGRA_EXT:
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_STENCIL:
- case GL_SRGB_EXT:
- case GL_SRGB_ALPHA_EXT:
- {
- static const FormatMap formatMap = BuildFormatMap();
- FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));
- return (iter != formatMap.end()) ? iter->second : GL_NONE;
- }
- default:
- return internalFormat;
- }
- }
unsigned int UniformComponentCount(GLenum type)
{
@@ -186,6 +40,7 @@
case GL_UNSIGNED_INT:
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -263,6 +118,7 @@
case GL_INT:
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -312,6 +168,7 @@
{
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -356,6 +213,7 @@
case GL_UNSIGNED_INT_VEC4:
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
case GL_SAMPLER_EXTERNAL_OES:
case GL_SAMPLER_3D_OES:
case GL_SAMPLER_2D_ARRAY:
@@ -465,22 +323,16 @@
return -1;
}
- bool IsCompressed(GLenum format, GLint clientVersion)
+ bool IsCompressed(GLint internalformat, GLint clientVersion)
{
- return ValidateCompressedFormat(format, clientVersion, true) == GL_NONE;
- }
-
- GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats)
- {
- switch(format)
+ switch(internalformat)
{
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
- return S3TC_SUPPORT ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
case GL_ETC1_RGB8_OES:
- return expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION;
+ return true;
case GL_COMPRESSED_R11_EAC:
case GL_COMPRESSED_SIGNED_R11_EAC:
case GL_COMPRESSED_RG11_EAC:
@@ -491,6 +343,7 @@
case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case GL_COMPRESSED_RGBA8_ETC2_EAC:
case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ return (clientVersion >= 3);
case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
@@ -519,27 +372,106 @@
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
- return (clientVersion >= 3) ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
+ return ASTC_SUPPORT && (clientVersion >= 3);
default:
- return expectCompressedFormats ? GL_INVALID_ENUM : GL_NONE; // Not compressed format
+ return false;
}
}
- GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)
+ bool IsSizedInternalFormat(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_ALPHA8_EXT:
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ case GL_LUMINANCE8_EXT:
+ case GL_R8:
+ case GL_R8UI:
+ case GL_R8I:
+ case GL_R16UI:
+ case GL_R16I:
+ case GL_R32UI:
+ case GL_R32I:
+ case GL_RG8:
+ case GL_RG8UI:
+ case GL_RG8I:
+ case GL_RG16UI:
+ case GL_RG16I:
+ case GL_RG32UI:
+ case GL_RG32I:
+ case GL_SRGB8_ALPHA8:
+ case GL_RGB8UI:
+ case GL_RGB8I:
+ case GL_RGB16UI:
+ case GL_RGB16I:
+ case GL_RGB32UI:
+ case GL_RGB32I:
+ case GL_RG8_SNORM:
+ case GL_R8_SNORM:
+ case GL_RGB10_A2:
+ case GL_RGBA8UI:
+ case GL_RGBA8I:
+ case GL_RGB10_A2UI:
+ case GL_RGBA16UI:
+ case GL_RGBA16I:
+ case GL_RGBA32I:
+ case GL_RGBA32UI:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ case GL_RGB8:
+ case GL_RGBA8:
+ case GL_BGRA8_EXT: // GL_APPLE_texture_format_BGRA8888
+ case GL_R16F:
+ case GL_RG16F:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB16F:
+ case GL_RGBA16F:
+ case GL_R32F:
+ case GL_RG32F:
+ case GL_RGB32F:
+ case GL_RGBA32F:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32_OES:
+ case GL_DEPTH_COMPONENT32F:
+ case GL_DEPTH32F_STENCIL8:
+ case GL_DEPTH_COMPONENT16:
+ case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES:
+ case GL_RGBA8_SNORM:
+ case GL_SRGB8:
+ case GL_RGB8_SNORM:
+ case GL_RGB9_E5:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture, GLint clientVersion)
{
if(!texture)
{
return GL_INVALID_OPERATION;
}
- if(compressed != texture->isCompressed(target, level))
- {
- return GL_INVALID_OPERATION;
- }
+ GLenum sizedInternalFormat = texture->getFormat(target, level);
- if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))
+ if(compressed)
{
- return GL_INVALID_OPERATION;
+ if(format != sizedInternalFormat)
+ {
+ return GL_INVALID_OPERATION;
+ }
+ }
+ else if(!copy) // CopyTexSubImage doesn't have format/type parameters.
+ {
+ GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target, clientVersion);
+ if(validationError != GL_NO_ERROR)
+ {
+ return validationError;
+ }
}
if(compressed)
@@ -557,10 +489,11 @@
return GL_INVALID_VALUE;
}
- return GL_NONE;
+ return GL_NO_ERROR;
}
- GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)
+ GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, Texture *texture, GLint clientVersion)
{
if(!texture)
{
@@ -572,9 +505,15 @@
return GL_INVALID_OPERATION;
}
- if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level)))
+ if(!copy)
{
- return GL_INVALID_OPERATION;
+ GLenum sizedInternalFormat = texture->getFormat(target, level);
+
+ GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target, clientVersion);
+ if(validationError != GL_NO_ERROR)
+ {
+ return validationError;
+ }
}
if(compressed)
@@ -594,7 +533,85 @@
return GL_INVALID_VALUE;
}
- return GL_NONE;
+ return GL_NO_ERROR;
+ }
+
+ bool ValidateCopyFormats(GLenum textureFormat, GLenum colorbufferFormat)
+ {
+ ASSERT(!gl::IsUnsizedInternalFormat(textureFormat));
+ ASSERT(!gl::IsUnsizedInternalFormat(colorbufferFormat));
+
+ if(GetColorComponentType(textureFormat) == GL_NONE)
+ {
+ return error(GL_INVALID_ENUM, false);
+ }
+
+ if(GetColorComponentType(colorbufferFormat) != GetColorComponentType(textureFormat))
+ {
+ return error(GL_INVALID_OPERATION, false);
+ }
+
+ if(GetColorEncoding(colorbufferFormat) != GetColorEncoding(textureFormat))
+ {
+ return error(GL_INVALID_OPERATION, false);
+ }
+
+ GLenum baseTexureFormat = gl::GetBaseInternalFormat(textureFormat);
+ GLenum baseColorbufferFormat = gl::GetBaseInternalFormat(colorbufferFormat);
+
+ // [OpenGL ES 2.0.24] table 3.9
+ // [OpenGL ES 3.0.5] table 3.16
+ switch(baseTexureFormat)
+ {
+ case GL_ALPHA:
+ if(baseColorbufferFormat != GL_ALPHA &&
+ baseColorbufferFormat != GL_RGBA)
+ {
+ return error(GL_INVALID_OPERATION, false);
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ if(baseColorbufferFormat != GL_RGBA &&
+ baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888
+ {
+ return error(GL_INVALID_OPERATION, false);
+ }
+ break;
+ case GL_LUMINANCE:
+ case GL_RED:
+ if(baseColorbufferFormat != GL_RED &&
+ baseColorbufferFormat != GL_RG &&
+ baseColorbufferFormat != GL_RGB &&
+ baseColorbufferFormat != GL_RGBA)
+ {
+ return error(GL_INVALID_OPERATION, false);
+ }
+ break;
+ case GL_RG:
+ if(baseColorbufferFormat != GL_RG &&
+ baseColorbufferFormat != GL_RGB &&
+ baseColorbufferFormat != GL_RGBA)
+ {
+ return error(GL_INVALID_OPERATION, false);
+ }
+ break;
+ case GL_RGB:
+ if(baseColorbufferFormat != GL_RGB &&
+ baseColorbufferFormat != GL_RGBA)
+ {
+ return error(GL_INVALID_OPERATION, false);
+ }
+ break;
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL_OES:
+ return error(GL_INVALID_OPERATION, false);
+ case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 nor GL_APPLE_texture_format_BGRA8888 mention the format to be accepted by glCopyTexImage2D.
+ default:
+ return error(GL_INVALID_ENUM, false);
+ }
+
+ return true;
}
bool IsValidReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type, GLint clientVersion)
@@ -620,16 +637,16 @@
}
}
- Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
+ Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
if(!colorbuffer)
{
return false;
}
- sw::Format internalformat = colorbuffer->getInternalFormat();
+ GLint internalformat = colorbuffer->getFormat();
- if(sw::Surface::isNormalizedInteger(internalformat))
+ if(IsNormalizedInteger(internalformat))
{
// Combination always supported by normalized fixed-point rendering surfaces.
if(format == GL_RGBA && type == GL_UNSIGNED_BYTE)
@@ -648,7 +665,7 @@
}
}
}
- else if(sw::Surface::isFloatFormat(internalformat))
+ else if(IsFloatFormat(internalformat))
{
// Combination always supported by floating-point rendering surfaces.
// Supported in OpenGL ES 2.0 due to GL_EXT_color_buffer_half_float.
@@ -657,7 +674,7 @@
return true;
}
}
- else if(sw::Surface::isSignedNonNormalizedInteger(internalformat))
+ else if(IsSignedNonNormalizedInteger(internalformat))
{
ASSERT(clientVersion >= 3);
@@ -666,7 +683,7 @@
return true;
}
}
- else if(sw::Surface::isUnsignedNonNormalizedInteger(internalformat))
+ else if(IsUnsignedNonNormalizedInteger(internalformat))
{
ASSERT(clientVersion >= 3);
@@ -698,7 +715,7 @@
}
// Additional third combination accepted by OpenGL ES 3.0.
- if(internalformat == sw::FORMAT_A2B10G10R10)
+ if(internalformat == GL_RGB10_A2)
{
ASSERT(clientVersion >= 3);
@@ -753,10 +770,10 @@
bool IsTextureTarget(GLenum target)
{
- return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
+ return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_RECTANGLE_ARB;
}
- bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion)
+ GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target, GLint clientVersion)
{
switch(type)
{
@@ -780,11 +797,11 @@
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
if(clientVersion < 3)
{
- return error(GL_INVALID_ENUM, false);
+ return GL_INVALID_ENUM;
}
break;
default:
- return error(GL_INVALID_ENUM, false);
+ return GL_INVALID_ENUM;
}
switch(format)
@@ -795,93 +812,138 @@
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
- case GL_DEPTH_STENCIL: // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
- case GL_DEPTH_COMPONENT: // GL_OES_depth_texture
case GL_RED_EXT: // GL_EXT_texture_rg
case GL_RG_EXT: // GL_EXT_texture_rg
break;
+ case GL_DEPTH_STENCIL: // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
+ case GL_DEPTH_COMPONENT: // GL_OES_depth_texture
+ switch(target)
+ {
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X: // GL_OES_depth_texture_cube_map
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
case GL_RED_INTEGER:
case GL_RG_INTEGER:
case GL_RGB_INTEGER:
case GL_RGBA_INTEGER:
if(clientVersion < 3)
{
- return error(GL_INVALID_ENUM, false);
+ return GL_INVALID_ENUM;
}
break;
default:
- return error(GL_INVALID_ENUM, false);
+ return GL_INVALID_ENUM;
}
if((GLenum)internalformat != format)
{
- if(clientVersion < 3)
+ if(gl::IsUnsizedInternalFormat(internalformat))
{
- return error(GL_INVALID_OPERATION, false);
+ return GL_INVALID_OPERATION;
}
- switch(internalformat)
+ if(!IsSizedInternalFormat(internalformat))
{
- case GL_R8:
- case GL_R8UI:
- case GL_R8I:
- case GL_R16UI:
- case GL_R16I:
- case GL_R32UI:
- case GL_R32I:
- case GL_RG8:
- case GL_RG8UI:
- case GL_RG8I:
- case GL_RG16UI:
- case GL_RG16I:
- case GL_RG32UI:
- case GL_RG32I:
- case GL_SRGB8_ALPHA8:
- case GL_RGB8UI:
- case GL_RGB8I:
- case GL_RGB16UI:
- case GL_RGB16I:
- case GL_RGB32UI:
- case GL_RGB32I:
- case GL_RG8_SNORM:
- case GL_R8_SNORM:
- case GL_RGB10_A2:
- case GL_RGBA8UI:
- case GL_RGBA8I:
- case GL_RGB10_A2UI:
- case GL_RGBA16UI:
- case GL_RGBA16I:
- case GL_RGBA32I:
- case GL_RGBA32UI:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGB565:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
- case GL_R16F:
- case GL_RG16F:
- case GL_R11F_G11F_B10F:
- case GL_RGB16F:
- case GL_RGBA16F:
- case GL_R32F:
- case GL_RG32F:
- case GL_RGB32F:
- case GL_RGBA32F:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32_OES:
- case GL_DEPTH_COMPONENT32F:
- case GL_DEPTH32F_STENCIL8:
- case GL_DEPTH_COMPONENT16:
- case GL_STENCIL_INDEX8:
- case GL_DEPTH24_STENCIL8_OES:
- case GL_RGBA8_SNORM:
- case GL_SRGB8:
- case GL_RGB8_SNORM:
- case GL_RGB9_E5:
+ return GL_INVALID_VALUE;
+ }
+ }
+
+ if((GLenum)internalformat == format)
+ {
+ // Validate format, type, and unsized internalformat combinations [OpenGL ES 3.0 Table 3.3]
+ switch(format)
+ {
+ case GL_RGBA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_FLOAT: // GL_OES_texture_float
+ case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_RGB:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_FLOAT: // GL_OES_texture_float
+ case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_FLOAT: // GL_OES_texture_float
+ case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_DEPTH_COMPONENT:
+ switch(type)
+ {
+ case GL_UNSIGNED_SHORT: // GL_OES_depth_texture
+ case GL_UNSIGNED_INT: // GL_OES_depth_texture
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ switch(type)
+ {
+ case GL_UNSIGNED_INT_24_8_OES: // GL_OES_packed_depth_stencil
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_RED_EXT:
+ case GL_RG_EXT:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: // GL_EXT_texture_rg
+ case GL_FLOAT: // GL_EXT_texture_rg + GL_OES_texture_float
+ case GL_HALF_FLOAT_OES: // GL_EXT_texture_rg + GL_OES_texture_half_float
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+ case GL_BGRA_EXT:
+ if(type != GL_UNSIGNED_BYTE) // GL_APPLE_texture_format_BGRA8888 / GL_EXT_texture_format_BGRA8888
+ {
+ return GL_INVALID_OPERATION;
+ }
break;
default:
- return error(GL_INVALID_ENUM, false);
+ UNREACHABLE(format);
+ return GL_INVALID_ENUM;
}
+
+ return GL_NO_ERROR;
}
// Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
@@ -895,13 +957,13 @@
{
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
- case GL_HALF_FLOAT_OES: break;
+ case GL_HALF_FLOAT_OES: VALIDATE_INTERNALFORMAT(GL_RGBA16F)
case GL_UNSIGNED_SHORT_4_4_4_4: VALIDATE_INTERNALFORMAT(GL_RGBA4)
case GL_UNSIGNED_SHORT_5_5_5_1: VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_RGBA_INTEGER:
@@ -914,7 +976,7 @@
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32I)
case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_RGB:
@@ -922,25 +984,25 @@
{
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
- case GL_HALF_FLOAT_OES: break;
+ case GL_HALF_FLOAT_OES: VALIDATE_INTERNALFORMAT(GL_RGB16F)
case GL_UNSIGNED_SHORT_5_6_5: VALIDATE_INTERNALFORMAT(GL_RGB565)
case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
case GL_UNSIGNED_INT_5_9_9_9_REV: VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_RGB_INTEGER:
switch(type)
{
- case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8UI)
- case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8I)
- case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI)
- case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I)
- case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI)
- case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I)
- default: return error(GL_INVALID_OPERATION, false);
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8UI)
+ case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8I)
+ case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI)
+ case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I)
+ case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI)
+ case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I)
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_RG:
@@ -948,10 +1010,9 @@
{
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
- case GL_HALF_FLOAT_OES: break;
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_RG_INTEGER:
@@ -963,7 +1024,7 @@
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RG32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_RG32I)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_RED:
@@ -971,10 +1032,9 @@
{
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8_SNORM)
- case GL_HALF_FLOAT_OES: break;
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_R16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_RED_INTEGER:
@@ -986,7 +1046,7 @@
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_R16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_R32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_R32I)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_DEPTH_COMPONENT:
@@ -995,7 +1055,7 @@
case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_DEPTH_STENCIL:
@@ -1003,59 +1063,112 @@
{
case GL_UNSIGNED_INT_24_8: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
- default: return error(GL_INVALID_OPERATION, false);
+ default: return GL_INVALID_OPERATION;
}
break;
case GL_LUMINANCE_ALPHA:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT)
+ case GL_HALF_FLOAT_OES: VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA16F_EXT)
+ case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA16F_EXT)
+ case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA16F_EXT)
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
case GL_LUMINANCE:
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT)
+ case GL_HALF_FLOAT_OES: VALIDATE_INTERNALFORMAT(GL_LUMINANCE16F_EXT)
+ case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE16F_EXT)
+ case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE32F_EXT, GL_LUMINANCE16F_EXT)
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
case GL_ALPHA:
switch(type)
{
- case GL_UNSIGNED_BYTE:
- case GL_HALF_FLOAT_OES:
- case GL_FLOAT:
- break;
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT)
+ case GL_HALF_FLOAT_OES: VALIDATE_INTERNALFORMAT(GL_ALPHA16F_EXT)
+ case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_ALPHA16F_EXT)
+ case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_ALPHA32F_EXT, GL_ALPHA16F_EXT)
default:
- return error(GL_INVALID_OPERATION, false);
+ return GL_INVALID_OPERATION;
}
break;
- case GL_BGRA_EXT:
- if(type != GL_UNSIGNED_BYTE)
+ case GL_BGRA_EXT: // GL_APPLE_texture_format_BGRA8888
+ switch(type)
{
- return error(GL_INVALID_OPERATION, false);
+ case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_BGRA8_EXT)
+ default: return GL_INVALID_OPERATION;
}
break;
default:
UNREACHABLE(format);
- return error(GL_INVALID_ENUM, false);
+ return GL_INVALID_ENUM;
}
#undef VALIDATE_INTERNALFORMAT
- if((GLenum)internalformat != format && !validSizedInternalformat)
+ if(!validSizedInternalformat)
{
- return error(GL_INVALID_OPERATION, false);
+ return GL_INVALID_OPERATION;
}
- return true;
+ return GL_NO_ERROR;
}
- bool IsColorRenderable(GLenum internalformat, GLint clientVersion, bool isTexture)
+ GLsizei GetTypeSize(GLenum type)
{
+ switch(type)
+ {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ return 1;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_HALF_FLOAT_OES:
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ case GL_HALF_FLOAT:
+ return 2;
+ case GL_FLOAT:
+ case GL_UNSIGNED_INT_24_8:
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ return 4;
+ default:
+ UNREACHABLE(type);
+ break;
+ }
+
+ return 1;
+ }
+
+ bool IsColorRenderable(GLint internalformat, GLint clientVersion)
+ {
+ if(IsCompressed(internalformat, clientVersion))
+ {
+ return false;
+ }
+
switch(internalformat)
{
- case GL_RED_EXT:
- case GL_RG_EXT:
- case GL_RGB:
- case GL_RGBA:
- return isTexture;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
- case GL_R8_EXT:
- case GL_RG8_EXT:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
+ case GL_R8:
+ case GL_RG8:
+ case GL_RGB8:
+ case GL_RGBA8:
case GL_R16F:
case GL_RG16F:
case GL_RGB16F:
@@ -1064,7 +1177,7 @@
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
- case GL_BGRA8_EXT:
+ case GL_BGRA8_EXT: // GL_EXT_texture_format_BGRA8888
return true;
case GL_R8UI:
case GL_R8I:
@@ -1089,6 +1202,13 @@
case GL_RGBA32UI:
case GL_R11F_G11F_B10F:
return clientVersion >= 3;
+ case GL_R8_SNORM:
+ case GL_RG8_SNORM:
+ case GL_RGB8_SNORM:
+ case GL_RGBA8_SNORM:
+ case GL_ALPHA8_EXT:
+ case GL_LUMINANCE8_EXT:
+ case GL_LUMINANCE8_ALPHA8_EXT:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_COMPONENT32F:
@@ -1104,8 +1224,13 @@
return false;
}
- bool IsDepthRenderable(GLenum internalformat, GLint clientVersion)
+ bool IsDepthRenderable(GLint internalformat, GLint clientVersion)
{
+ if(IsCompressed(internalformat, clientVersion))
+ {
+ return false;
+ }
+
switch(internalformat)
{
case GL_DEPTH_COMPONENT24:
@@ -1143,8 +1268,8 @@
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
+ case GL_RGB8:
+ case GL_RGBA8:
case GL_RED:
case GL_RG:
case GL_RGB:
@@ -1158,6 +1283,10 @@
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
+ case GL_R8_SNORM:
+ case GL_RG8_SNORM:
+ case GL_RGB8_SNORM:
+ case GL_RGBA8_SNORM:
return false;
default:
UNIMPLEMENTED();
@@ -1166,8 +1295,13 @@
return false;
}
- bool IsStencilRenderable(GLenum internalformat, GLint clientVersion)
+ bool IsStencilRenderable(GLint internalformat, GLint clientVersion)
{
+ if(IsCompressed(internalformat, clientVersion))
+ {
+ return false;
+ }
+
switch(internalformat)
{
case GL_STENCIL_INDEX8:
@@ -1201,8 +1335,8 @@
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
+ case GL_RGB8:
+ case GL_RGBA8:
case GL_RED:
case GL_RG:
case GL_RGB:
@@ -1220,6 +1354,10 @@
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_COMPONENT32F:
+ case GL_R8_SNORM:
+ case GL_RG8_SNORM:
+ case GL_RGB8_SNORM:
+ case GL_RGBA8_SNORM:
return false;
default:
UNIMPLEMENTED();
@@ -1228,6 +1366,414 @@
return false;
}
+ bool IsMipmappable(GLint internalformat, GLint clientVersion)
+ {
+ if(IsNonNormalizedInteger(internalformat))
+ {
+ return false;
+ }
+
+ switch(internalformat)
+ {
+ case GL_ALPHA8_EXT:
+ case GL_LUMINANCE8_EXT:
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ return true;
+ default:
+ return IsColorRenderable(internalformat, clientVersion);
+ }
+ }
+
+ GLuint GetAlphaSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_NONE: return 0;
+ case GL_RGBA4: return 4;
+ case GL_RGB5_A1: return 1;
+ case GL_RGB565: return 0;
+ case GL_R8: return 0;
+ case GL_RG8: return 0;
+ case GL_RGB8: return 0;
+ case GL_RGBA8: return 8;
+ case GL_R16F: return 0;
+ case GL_RG16F: return 0;
+ case GL_RGB16F: return 0;
+ case GL_RGBA16F: return 16;
+ case GL_R32F: return 0;
+ case GL_RG32F: return 0;
+ case GL_RGB32F: return 0;
+ case GL_RGBA32F: return 32;
+ case GL_BGRA8_EXT: return 8;
+ case GL_R8UI: return 0;
+ case GL_R8I: return 0;
+ case GL_R16UI: return 0;
+ case GL_R16I: return 0;
+ case GL_R32UI: return 0;
+ case GL_R32I: return 0;
+ case GL_RG8UI: return 0;
+ case GL_RG8I: return 0;
+ case GL_RG16UI: return 0;
+ case GL_RG16I: return 0;
+ case GL_RG32UI: return 0;
+ case GL_RG32I: return 0;
+ case GL_SRGB8_ALPHA8: return 8;
+ case GL_RGB10_A2: return 2;
+ case GL_RGBA8UI: return 8;
+ case GL_RGBA8I: return 8;
+ case GL_RGB10_A2UI: return 2;
+ case GL_RGBA16UI: return 16;
+ case GL_RGBA16I: return 16;
+ case GL_RGBA32I: return 32;
+ case GL_RGBA32UI: return 32;
+ case GL_R11F_G11F_B10F: return 0;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetRedSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_NONE: return 0;
+ case GL_RGBA4: return 4;
+ case GL_RGB5_A1: return 5;
+ case GL_RGB565: return 5;
+ case GL_R8: return 8;
+ case GL_RG8: return 8;
+ case GL_RGB8: return 8;
+ case GL_RGBA8: return 8;
+ case GL_R16F: return 16;
+ case GL_RG16F: return 16;
+ case GL_RGB16F: return 16;
+ case GL_RGBA16F: return 16;
+ case GL_R32F: return 32;
+ case GL_RG32F: return 32;
+ case GL_RGB32F: return 32;
+ case GL_RGBA32F: return 32;
+ case GL_BGRA8_EXT: return 8;
+ case GL_R8UI: return 8;
+ case GL_R8I: return 8;
+ case GL_R16UI: return 16;
+ case GL_R16I: return 16;
+ case GL_R32UI: return 32;
+ case GL_R32I: return 32;
+ case GL_RG8UI: return 8;
+ case GL_RG8I: return 8;
+ case GL_RG16UI: return 16;
+ case GL_RG16I: return 16;
+ case GL_RG32UI: return 32;
+ case GL_RG32I: return 32;
+ case GL_SRGB8_ALPHA8: return 8;
+ case GL_RGB10_A2: return 10;
+ case GL_RGBA8UI: return 8;
+ case GL_RGBA8I: return 8;
+ case GL_RGB10_A2UI: return 10;
+ case GL_RGBA16UI: return 16;
+ case GL_RGBA16I: return 16;
+ case GL_RGBA32I: return 32;
+ case GL_RGBA32UI: return 32;
+ case GL_R11F_G11F_B10F: return 11;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetGreenSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_NONE: return 0;
+ case GL_RGBA4: return 4;
+ case GL_RGB5_A1: return 5;
+ case GL_RGB565: return 6;
+ case GL_R8: return 0;
+ case GL_RG8: return 8;
+ case GL_RGB8: return 8;
+ case GL_RGBA8: return 8;
+ case GL_R16F: return 0;
+ case GL_RG16F: return 16;
+ case GL_RGB16F: return 16;
+ case GL_RGBA16F: return 16;
+ case GL_R32F: return 0;
+ case GL_RG32F: return 32;
+ case GL_RGB32F: return 32;
+ case GL_RGBA32F: return 32;
+ case GL_BGRA8_EXT: return 8;
+ case GL_R8UI: return 0;
+ case GL_R8I: return 0;
+ case GL_R16UI: return 0;
+ case GL_R16I: return 0;
+ case GL_R32UI: return 0;
+ case GL_R32I: return 0;
+ case GL_RG8UI: return 8;
+ case GL_RG8I: return 8;
+ case GL_RG16UI: return 16;
+ case GL_RG16I: return 16;
+ case GL_RG32UI: return 32;
+ case GL_RG32I: return 32;
+ case GL_SRGB8_ALPHA8: return 8;
+ case GL_RGB10_A2: return 10;
+ case GL_RGBA8UI: return 8;
+ case GL_RGBA8I: return 8;
+ case GL_RGB10_A2UI: return 10;
+ case GL_RGBA16UI: return 16;
+ case GL_RGBA16I: return 16;
+ case GL_RGBA32I: return 32;
+ case GL_RGBA32UI: return 32;
+ case GL_R11F_G11F_B10F: return 11;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetBlueSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_NONE: return 0;
+ case GL_RGBA4: return 4;
+ case GL_RGB5_A1: return 5;
+ case GL_RGB565: return 5;
+ case GL_R8: return 0;
+ case GL_RG8: return 0;
+ case GL_RGB8: return 8;
+ case GL_RGBA8: return 8;
+ case GL_R16F: return 0;
+ case GL_RG16F: return 0;
+ case GL_RGB16F: return 16;
+ case GL_RGBA16F: return 16;
+ case GL_R32F: return 0;
+ case GL_RG32F: return 0;
+ case GL_RGB32F: return 32;
+ case GL_RGBA32F: return 32;
+ case GL_BGRA8_EXT: return 8;
+ case GL_R8UI: return 0;
+ case GL_R8I: return 0;
+ case GL_R16UI: return 0;
+ case GL_R16I: return 0;
+ case GL_R32UI: return 0;
+ case GL_R32I: return 0;
+ case GL_RG8UI: return 0;
+ case GL_RG8I: return 0;
+ case GL_RG16UI: return 0;
+ case GL_RG16I: return 0;
+ case GL_RG32UI: return 0;
+ case GL_RG32I: return 0;
+ case GL_SRGB8_ALPHA8: return 8;
+ case GL_RGB10_A2: return 10;
+ case GL_RGBA8UI: return 8;
+ case GL_RGBA8I: return 8;
+ case GL_RGB10_A2UI: return 10;
+ case GL_RGBA16UI: return 16;
+ case GL_RGBA16I: return 16;
+ case GL_RGBA32I: return 32;
+ case GL_RGBA32UI: return 32;
+ case GL_R11F_G11F_B10F: return 10;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetDepthSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_STENCIL_INDEX8: return 0;
+ case GL_DEPTH_COMPONENT16: return 16;
+ case GL_DEPTH_COMPONENT24: return 24;
+ case GL_DEPTH_COMPONENT32_OES: return 32;
+ case GL_DEPTH_COMPONENT32F: return 32;
+ case GL_DEPTH24_STENCIL8: return 24;
+ case GL_DEPTH32F_STENCIL8: return 32;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLuint GetStencilSize(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_STENCIL_INDEX8: return 8;
+ case GL_DEPTH_COMPONENT16: return 0;
+ case GL_DEPTH_COMPONENT24: return 0;
+ case GL_DEPTH_COMPONENT32_OES: return 0;
+ case GL_DEPTH_COMPONENT32F: return 0;
+ case GL_DEPTH24_STENCIL8: return 8;
+ case GL_DEPTH32F_STENCIL8: return 8;
+ default:
+ // UNREACHABLE(internalformat);
+ return 0;
+ }
+ }
+
+ GLenum GetColorComponentType(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_ALPHA8_EXT:
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ case GL_LUMINANCE8_EXT:
+ case GL_R8:
+ case GL_RG8:
+ case GL_SRGB8_ALPHA8:
+ case GL_RGB10_A2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ case GL_RGB8:
+ case GL_RGBA8:
+ case GL_SRGB8:
+ case GL_BGRA8_EXT:
+ return GL_UNSIGNED_NORMALIZED;
+ case GL_R8_SNORM:
+ case GL_RG8_SNORM:
+ case GL_RGB8_SNORM:
+ case GL_RGBA8_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case GL_R8UI:
+ case GL_R16UI:
+ case GL_R32UI:
+ case GL_RG8UI:
+ case GL_RG16UI:
+ case GL_RG32UI:
+ case GL_RGB8UI:
+ case GL_RGB16UI:
+ case GL_RGB32UI:
+ case GL_RGB10_A2UI:
+ case GL_RGBA16UI:
+ case GL_RGBA32UI:
+ case GL_RGBA8UI:
+ return GL_UNSIGNED_INT;
+ case GL_R8I:
+ case GL_R16I:
+ case GL_R32I:
+ case GL_RG8I:
+ case GL_RG16I:
+ case GL_RG32I:
+ case GL_RGB8I:
+ case GL_RGB16I:
+ case GL_RGB32I:
+ case GL_RGBA8I:
+ case GL_RGBA16I:
+ case GL_RGBA32I:
+ return GL_INT;
+ case GL_R16F:
+ case GL_RG16F:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB16F:
+ case GL_RGBA16F:
+ case GL_R32F:
+ case GL_RG32F:
+ case GL_RGB32F:
+ case GL_RGBA32F:
+ case GL_RGB9_E5:
+ return GL_FLOAT;
+ default:
+ // UNREACHABLE(internalformat);
+ return GL_NONE;
+ }
+ }
+
+ GLenum GetComponentType(GLint internalformat, GLenum attachment)
+ {
+ // Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED
+ switch(attachment)
+ {
+ case GL_COLOR_ATTACHMENT0:
+ case GL_COLOR_ATTACHMENT1:
+ case GL_COLOR_ATTACHMENT2:
+ case GL_COLOR_ATTACHMENT3:
+ case GL_COLOR_ATTACHMENT4:
+ case GL_COLOR_ATTACHMENT5:
+ case GL_COLOR_ATTACHMENT6:
+ case GL_COLOR_ATTACHMENT7:
+ case GL_COLOR_ATTACHMENT8:
+ case GL_COLOR_ATTACHMENT9:
+ case GL_COLOR_ATTACHMENT10:
+ case GL_COLOR_ATTACHMENT11:
+ case GL_COLOR_ATTACHMENT12:
+ case GL_COLOR_ATTACHMENT13:
+ case GL_COLOR_ATTACHMENT14:
+ case GL_COLOR_ATTACHMENT15:
+ case GL_COLOR_ATTACHMENT16:
+ case GL_COLOR_ATTACHMENT17:
+ case GL_COLOR_ATTACHMENT18:
+ case GL_COLOR_ATTACHMENT19:
+ case GL_COLOR_ATTACHMENT20:
+ case GL_COLOR_ATTACHMENT21:
+ case GL_COLOR_ATTACHMENT22:
+ case GL_COLOR_ATTACHMENT23:
+ case GL_COLOR_ATTACHMENT24:
+ case GL_COLOR_ATTACHMENT25:
+ case GL_COLOR_ATTACHMENT26:
+ case GL_COLOR_ATTACHMENT27:
+ case GL_COLOR_ATTACHMENT28:
+ case GL_COLOR_ATTACHMENT29:
+ case GL_COLOR_ATTACHMENT30:
+ case GL_COLOR_ATTACHMENT31:
+ return GetColorComponentType(internalformat);
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ // Only color buffers may have integer components.
+ return GL_FLOAT;
+ default:
+ UNREACHABLE(attachment);
+ return GL_NONE;
+ }
+ }
+
+ bool IsNormalizedInteger(GLint internalformat)
+ {
+ GLenum type = GetColorComponentType(internalformat);
+
+ return type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED;
+ }
+
+ bool IsNonNormalizedInteger(GLint internalformat)
+ {
+ GLenum type = GetColorComponentType(internalformat);
+
+ return type == GL_UNSIGNED_INT || type == GL_INT;
+ }
+
+ bool IsFloatFormat(GLint internalformat)
+ {
+ return GetColorComponentType(internalformat) == GL_FLOAT;
+ }
+
+ bool IsSignedNonNormalizedInteger(GLint internalformat)
+ {
+ return GetColorComponentType(internalformat) == GL_INT;
+ }
+
+ bool IsUnsignedNonNormalizedInteger(GLint internalformat)
+ {
+ return GetColorComponentType(internalformat) == GL_UNSIGNED_INT;
+ }
+
+ GLenum GetColorEncoding(GLint internalformat)
+ {
+ switch(internalformat)
+ {
+ case GL_SRGB8:
+ case GL_SRGB8_ALPHA8:
+ return GL_SRGB;
+ default:
+ // [OpenGL ES 3.0.5] section 6.1.13 page 242:
+ // If attachment is not a color attachment, or no data storage or texture image
+ // has been specified for the attachment, params will contain the value LINEAR.
+ return GL_LINEAR;
+ }
+ }
+
std::string ParseUniformName(const std::string &name, unsigned int *outSubscript)
{
// Strip any trailing array operator and retrieve the subscript
@@ -1374,6 +1920,32 @@
return sw::ADDRESSING_WRAP;
}
+ sw::CompareFunc ConvertCompareFunc(GLenum compareFunc, GLenum compareMode)
+ {
+ if(compareMode == GL_COMPARE_REF_TO_TEXTURE)
+ {
+ switch(compareFunc)
+ {
+ case GL_LEQUAL: return sw::COMPARE_LESSEQUAL;
+ case GL_GEQUAL: return sw::COMPARE_GREATEREQUAL;
+ case GL_LESS: return sw::COMPARE_LESS;
+ case GL_GREATER: return sw::COMPARE_GREATER;
+ case GL_EQUAL: return sw::COMPARE_EQUAL;
+ case GL_NOTEQUAL: return sw::COMPARE_NOTEQUAL;
+ case GL_ALWAYS: return sw::COMPARE_ALWAYS;
+ case GL_NEVER: return sw::COMPARE_NEVER;
+ default: UNREACHABLE(compareFunc);
+ }
+ }
+ else if(compareMode == GL_NONE)
+ {
+ return sw::COMPARE_BYPASS;
+ }
+ else UNREACHABLE(compareMode);
+
+ return sw::COMPARE_BYPASS;
+ };
+
sw::SwizzleType ConvertSwizzleType(GLenum swizzleType)
{
switch(swizzleType)
@@ -1421,15 +1993,12 @@
case GL_NEAREST:
case GL_LINEAR:
return sw::MIPMAP_NONE;
- break;
case GL_NEAREST_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_NEAREST:
return sw::MIPMAP_POINT;
- break;
case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
return sw::MIPMAP_LINEAR;
- break;
default:
UNREACHABLE(minFilter);
return sw::MIPMAP_NONE;
@@ -1443,12 +2012,13 @@
return sw::FILTER_ANISOTROPIC;
}
- sw::FilterType magFilterType = sw::FILTER_POINT;
switch(magFilter)
{
- case GL_NEAREST: magFilterType = sw::FILTER_POINT; break;
- case GL_LINEAR: magFilterType = sw::FILTER_LINEAR; break;
- default: UNREACHABLE(magFilter);
+ case GL_NEAREST:
+ case GL_LINEAR:
+ break;
+ default:
+ UNREACHABLE(magFilter);
}
switch(minFilter)
@@ -1456,14 +2026,14 @@
case GL_NEAREST:
case GL_NEAREST_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR:
- return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
+ return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
case GL_LINEAR:
case GL_LINEAR_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_LINEAR:
- return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
+ return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
default:
UNREACHABLE(minFilter);
- return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
+ return sw::FILTER_POINT;
}
}
@@ -1524,433 +2094,23 @@
return true;
}
-
- sw::Format ConvertRenderbufferFormat(GLenum format)
- {
- switch(format)
- {
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8_OES: return sw::FORMAT_A8B8G8R8;
- case GL_RGB565: return sw::FORMAT_R5G6B5;
- case GL_RGB8_OES: return sw::FORMAT_X8B8G8R8;
- case GL_DEPTH_COMPONENT16:
- case GL_STENCIL_INDEX8:
- case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
- case GL_DEPTH_COMPONENT32_OES:return sw::FORMAT_D32;
- case GL_R8: return sw::FORMAT_R8;
- case GL_RG8: return sw::FORMAT_G8R8;
- case GL_R8I: return sw::FORMAT_R8I;
- case GL_RG8I: return sw::FORMAT_G8R8I;
- case GL_RGB8I: return sw::FORMAT_X8B8G8R8I;
- case GL_RGBA8I: return sw::FORMAT_A8B8G8R8I;
- case GL_R8UI: return sw::FORMAT_R8UI;
- case GL_RG8UI: return sw::FORMAT_G8R8UI;
- case GL_RGB8UI: return sw::FORMAT_X8B8G8R8UI;
- case GL_RGBA8UI: return sw::FORMAT_A8B8G8R8UI;
- case GL_R16I: return sw::FORMAT_R16I;
- case GL_RG16I: return sw::FORMAT_G16R16I;
- case GL_RGB16I: return sw::FORMAT_X16B16G16R16I;
- case GL_RGBA16I: return sw::FORMAT_A16B16G16R16I;
- case GL_R16UI: return sw::FORMAT_R16UI;
- case GL_RG16UI: return sw::FORMAT_G16R16UI;
- case GL_RGB16UI: return sw::FORMAT_X16B16G16R16UI;
- case GL_RGB10_A2UI:
- case GL_RGBA16UI: return sw::FORMAT_A16B16G16R16UI;
- case GL_R32I: return sw::FORMAT_R32I;
- case GL_RG32I: return sw::FORMAT_G32R32I;
- case GL_RGB32I: return sw::FORMAT_X32B32G32R32I;
- case GL_RGBA32I: return sw::FORMAT_A32B32G32R32I;
- case GL_R32UI: return sw::FORMAT_R32UI;
- case GL_RG32UI: return sw::FORMAT_G32R32UI;
- case GL_RGB32UI: return sw::FORMAT_X32B32G32R32UI;
- case GL_RGBA32UI: return sw::FORMAT_A32B32G32R32UI;
- case GL_R16F: return sw::FORMAT_R16F;
- case GL_RG16F: return sw::FORMAT_G16R16F;
- case GL_R11F_G11F_B10F:
- case GL_RGB16F: return sw::FORMAT_B16G16R16F;
- case GL_RGBA16F: return sw::FORMAT_A16B16G16R16F;
- case GL_R32F: return sw::FORMAT_R32F;
- case GL_RG32F: return sw::FORMAT_G32R32F;
- case GL_RGB32F: return sw::FORMAT_B32G32R32F;
- case GL_RGBA32F: return sw::FORMAT_A32B32G32R32F;
- case GL_RGB10_A2: return sw::FORMAT_A2B10G10R10;
- case GL_SRGB8: return sw::FORMAT_SRGB8_X8;
- case GL_SRGB8_ALPHA8: return sw::FORMAT_SRGB8_A8;
- default: UNREACHABLE(format); return sw::FORMAT_NULL;
- }
- }
}
namespace sw2es
{
- unsigned int GetStencilSize(sw::Format stencilFormat)
- {
- switch(stencilFormat)
- {
- case sw::FORMAT_D24FS8:
- case sw::FORMAT_D24S8:
- case sw::FORMAT_D32FS8_TEXTURE:
- case sw::FORMAT_D32FS8_SHADOW:
- case sw::FORMAT_S8:
- return 8;
- // case sw::FORMAT_D24X4S4:
- // return 4;
- // case sw::FORMAT_D15S1:
- // return 1;
- // case sw::FORMAT_D16_LOCKABLE:
- case sw::FORMAT_D32:
- case sw::FORMAT_D24X8:
- case sw::FORMAT_D32F_LOCKABLE:
- case sw::FORMAT_D16:
- return 0;
- // case sw::FORMAT_D32_LOCKABLE: return 0;
- // case sw::FORMAT_S8_LOCKABLE: return 8;
- default:
- return 0;
- }
- }
-
- unsigned int GetAlphaSize(sw::Format colorFormat)
- {
- switch(colorFormat)
- {
- case sw::FORMAT_A16B16G16R16F:
- case sw::FORMAT_A16B16G16R16I:
- case sw::FORMAT_A16B16G16R16UI:
- return 16;
- case sw::FORMAT_A32B32G32R32F:
- case sw::FORMAT_A32B32G32R32I:
- case sw::FORMAT_A32B32G32R32UI:
- return 32;
- case sw::FORMAT_A2R10G10B10:
- return 2;
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_SRGB8_A8:
- case sw::FORMAT_A8B8G8R8I:
- case sw::FORMAT_A8B8G8R8UI:
- case sw::FORMAT_A8B8G8R8I_SNORM:
- return 8;
- case sw::FORMAT_A2B10G10R10:
- return 2;
- case sw::FORMAT_A1R5G5B5:
- return 1;
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- case sw::FORMAT_SRGB8_X8:
- case sw::FORMAT_R5G6B5:
- return 0;
- default:
- return 0;
- }
- }
-
- unsigned int GetRedSize(sw::Format colorFormat)
- {
- switch(colorFormat)
- {
- case sw::FORMAT_R16F:
- case sw::FORMAT_G16R16F:
- case sw::FORMAT_B16G16R16F:
- case sw::FORMAT_A16B16G16R16F:
- case sw::FORMAT_R16I:
- case sw::FORMAT_G16R16I:
- case sw::FORMAT_X16B16G16R16I:
- case sw::FORMAT_A16B16G16R16I:
- case sw::FORMAT_R16UI:
- case sw::FORMAT_G16R16UI:
- case sw::FORMAT_X16B16G16R16UI:
- case sw::FORMAT_A16B16G16R16UI:
- return 16;
- case sw::FORMAT_R32F:
- case sw::FORMAT_G32R32F:
- case sw::FORMAT_B32G32R32F:
- case sw::FORMAT_X32B32G32R32F:
- case sw::FORMAT_A32B32G32R32F:
- case sw::FORMAT_R32I:
- case sw::FORMAT_G32R32I:
- case sw::FORMAT_X32B32G32R32I:
- case sw::FORMAT_A32B32G32R32I:
- case sw::FORMAT_R32UI:
- case sw::FORMAT_G32R32UI:
- case sw::FORMAT_X32B32G32R32UI:
- case sw::FORMAT_A32B32G32R32UI:
- return 32;
- case sw::FORMAT_A2B10G10R10:
- case sw::FORMAT_A2R10G10B10:
- return 10;
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- case sw::FORMAT_SRGB8_A8:
- case sw::FORMAT_SRGB8_X8:
- case sw::FORMAT_R8:
- case sw::FORMAT_G8R8:
- case sw::FORMAT_R8I:
- case sw::FORMAT_G8R8I:
- case sw::FORMAT_X8B8G8R8I:
- case sw::FORMAT_A8B8G8R8I:
- case sw::FORMAT_R8UI:
- case sw::FORMAT_G8R8UI:
- case sw::FORMAT_X8B8G8R8UI:
- case sw::FORMAT_A8B8G8R8UI:
- case sw::FORMAT_R8I_SNORM:
- case sw::FORMAT_G8R8I_SNORM:
- case sw::FORMAT_X8B8G8R8I_SNORM:
- case sw::FORMAT_A8B8G8R8I_SNORM:
- return 8;
- case sw::FORMAT_A1R5G5B5:
- case sw::FORMAT_R5G6B5:
- return 5;
- default:
- return 0;
- }
- }
-
- unsigned int GetGreenSize(sw::Format colorFormat)
- {
- switch(colorFormat)
- {
- case sw::FORMAT_G16R16F:
- case sw::FORMAT_B16G16R16F:
- case sw::FORMAT_A16B16G16R16F:
- case sw::FORMAT_G16R16I:
- case sw::FORMAT_X16B16G16R16I:
- case sw::FORMAT_A16B16G16R16I:
- case sw::FORMAT_G16R16UI:
- case sw::FORMAT_X16B16G16R16UI:
- case sw::FORMAT_A16B16G16R16UI:
- return 16;
- case sw::FORMAT_G32R32F:
- case sw::FORMAT_B32G32R32F:
- case sw::FORMAT_X32B32G32R32F:
- case sw::FORMAT_A32B32G32R32F:
- case sw::FORMAT_G32R32I:
- case sw::FORMAT_X32B32G32R32I:
- case sw::FORMAT_A32B32G32R32I:
- case sw::FORMAT_G32R32UI:
- case sw::FORMAT_X32B32G32R32UI:
- case sw::FORMAT_A32B32G32R32UI:
- return 32;
- case sw::FORMAT_A2B10G10R10:
- case sw::FORMAT_A2R10G10B10:
- return 10;
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- case sw::FORMAT_SRGB8_A8:
- case sw::FORMAT_SRGB8_X8:
- case sw::FORMAT_G8R8:
- case sw::FORMAT_G8R8I:
- case sw::FORMAT_X8B8G8R8I:
- case sw::FORMAT_A8B8G8R8I:
- case sw::FORMAT_G8R8UI:
- case sw::FORMAT_X8B8G8R8UI:
- case sw::FORMAT_A8B8G8R8UI:
- case sw::FORMAT_G8R8I_SNORM:
- case sw::FORMAT_X8B8G8R8I_SNORM:
- case sw::FORMAT_A8B8G8R8I_SNORM:
- return 8;
- case sw::FORMAT_A1R5G5B5:
- return 5;
- case sw::FORMAT_R5G6B5:
- return 6;
- default:
- return 0;
- }
- }
-
- unsigned int GetBlueSize(sw::Format colorFormat)
- {
- switch(colorFormat)
- {
- case sw::FORMAT_B16G16R16F:
- case sw::FORMAT_A16B16G16R16F:
- case sw::FORMAT_X16B16G16R16I:
- case sw::FORMAT_A16B16G16R16I:
- case sw::FORMAT_X16B16G16R16UI:
- case sw::FORMAT_A16B16G16R16UI:
- return 16;
- case sw::FORMAT_B32G32R32F:
- case sw::FORMAT_X32B32G32R32F:
- case sw::FORMAT_A32B32G32R32F:
- case sw::FORMAT_X32B32G32R32I:
- case sw::FORMAT_A32B32G32R32I:
- case sw::FORMAT_X32B32G32R32UI:
- case sw::FORMAT_A32B32G32R32UI:
- return 32;
- case sw::FORMAT_A2B10G10R10:
- case sw::FORMAT_A2R10G10B10:
- return 10;
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- case sw::FORMAT_SRGB8_A8:
- case sw::FORMAT_SRGB8_X8:
- case sw::FORMAT_X8B8G8R8I:
- case sw::FORMAT_A8B8G8R8I:
- case sw::FORMAT_X8B8G8R8UI:
- case sw::FORMAT_A8B8G8R8UI:
- case sw::FORMAT_X8B8G8R8I_SNORM:
- case sw::FORMAT_A8B8G8R8I_SNORM:
- return 8;
- case sw::FORMAT_A1R5G5B5:
- case sw::FORMAT_R5G6B5:
- return 5;
- default:
- return 0;
- }
- }
-
- unsigned int GetDepthSize(sw::Format depthFormat)
- {
- switch(depthFormat)
- {
- // case sw::FORMAT_D16_LOCKABLE: return 16;
- case sw::FORMAT_D32: return 32;
- // case sw::FORMAT_D15S1: return 15;
- case sw::FORMAT_D24S8: return 24;
- case sw::FORMAT_D24X8: return 24;
- // case sw::FORMAT_D24X4S4: return 24;
- case sw::FORMAT_DF16S8:
- case sw::FORMAT_D16: return 16;
- case sw::FORMAT_D32F:
- case sw::FORMAT_D32F_COMPLEMENTARY:
- case sw::FORMAT_D32F_LOCKABLE: return 32;
- case sw::FORMAT_DF24S8:
- case sw::FORMAT_D24FS8: return 24;
- // case sw::FORMAT_D32_LOCKABLE: return 32;
- // case sw::FORMAT_S8_LOCKABLE: return 0;
- case sw::FORMAT_D32FS8_SHADOW:
- case sw::FORMAT_D32FS8_TEXTURE: return 32;
- default: return 0;
- }
- }
-
- GLenum GetComponentType(sw::Format format, GLenum attachment)
- {
- // Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED
- switch(attachment)
- {
- case GL_COLOR_ATTACHMENT0:
- case GL_COLOR_ATTACHMENT1:
- case GL_COLOR_ATTACHMENT2:
- case GL_COLOR_ATTACHMENT3:
- case GL_COLOR_ATTACHMENT4:
- case GL_COLOR_ATTACHMENT5:
- case GL_COLOR_ATTACHMENT6:
- case GL_COLOR_ATTACHMENT7:
- case GL_COLOR_ATTACHMENT8:
- case GL_COLOR_ATTACHMENT9:
- case GL_COLOR_ATTACHMENT10:
- case GL_COLOR_ATTACHMENT11:
- case GL_COLOR_ATTACHMENT12:
- case GL_COLOR_ATTACHMENT13:
- case GL_COLOR_ATTACHMENT14:
- case GL_COLOR_ATTACHMENT15:
- case GL_COLOR_ATTACHMENT16:
- case GL_COLOR_ATTACHMENT17:
- case GL_COLOR_ATTACHMENT18:
- case GL_COLOR_ATTACHMENT19:
- case GL_COLOR_ATTACHMENT20:
- case GL_COLOR_ATTACHMENT21:
- case GL_COLOR_ATTACHMENT22:
- case GL_COLOR_ATTACHMENT23:
- case GL_COLOR_ATTACHMENT24:
- case GL_COLOR_ATTACHMENT25:
- case GL_COLOR_ATTACHMENT26:
- case GL_COLOR_ATTACHMENT27:
- case GL_COLOR_ATTACHMENT28:
- case GL_COLOR_ATTACHMENT29:
- case GL_COLOR_ATTACHMENT30:
- case GL_COLOR_ATTACHMENT31:
- switch(format)
- {
- case sw::FORMAT_R8I:
- case sw::FORMAT_G8R8I:
- case sw::FORMAT_X8B8G8R8I:
- case sw::FORMAT_A8B8G8R8I:
- case sw::FORMAT_R16I:
- case sw::FORMAT_G16R16I:
- case sw::FORMAT_X16B16G16R16I:
- case sw::FORMAT_A16B16G16R16I:
- case sw::FORMAT_R32I:
- case sw::FORMAT_G32R32I:
- case sw::FORMAT_X32B32G32R32I:
- case sw::FORMAT_A32B32G32R32I:
- return GL_INT;
- case sw::FORMAT_R8UI:
- case sw::FORMAT_G8R8UI:
- case sw::FORMAT_X8B8G8R8UI:
- case sw::FORMAT_A8B8G8R8UI:
- case sw::FORMAT_R16UI:
- case sw::FORMAT_G16R16UI:
- case sw::FORMAT_X16B16G16R16UI:
- case sw::FORMAT_A16B16G16R16UI:
- case sw::FORMAT_R32UI:
- case sw::FORMAT_G32R32UI:
- case sw::FORMAT_X32B32G32R32UI:
- case sw::FORMAT_A32B32G32R32UI:
- return GL_UNSIGNED_INT;
- case sw::FORMAT_R16F:
- case sw::FORMAT_G16R16F:
- case sw::FORMAT_B16G16R16F:
- case sw::FORMAT_A16B16G16R16F:
- case sw::FORMAT_R32F:
- case sw::FORMAT_G32R32F:
- case sw::FORMAT_B32G32R32F:
- case sw::FORMAT_X32B32G32R32F:
- case sw::FORMAT_A32B32G32R32F:
- return GL_FLOAT;
- case sw::FORMAT_R8:
- case sw::FORMAT_G8R8:
- case sw::FORMAT_A2B10G10R10:
- case sw::FORMAT_A2R10G10B10:
- case sw::FORMAT_A8R8G8B8:
- case sw::FORMAT_A8B8G8R8:
- case sw::FORMAT_X8R8G8B8:
- case sw::FORMAT_X8B8G8R8:
- case sw::FORMAT_SRGB8_A8:
- case sw::FORMAT_SRGB8_X8:
- case sw::FORMAT_A1R5G5B5:
- case sw::FORMAT_R5G6B5:
- return GL_UNSIGNED_NORMALIZED;
- case sw::FORMAT_R8I_SNORM:
- case sw::FORMAT_X8B8G8R8I_SNORM:
- case sw::FORMAT_A8B8G8R8I_SNORM:
- case sw::FORMAT_G8R8I_SNORM:
- return GL_SIGNED_NORMALIZED;
- default:
- UNREACHABLE(format);
- return GL_NONE;
- }
- case GL_DEPTH_ATTACHMENT:
- case GL_STENCIL_ATTACHMENT:
- // Only color buffers may have integer components.
- return GL_FLOAT;
- default:
- UNREACHABLE(attachment);
- return GL_NONE;
- }
- }
-
GLenum ConvertBackBufferFormat(sw::Format format)
{
switch(format)
{
case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
- case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;
- case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;
+ case sw::FORMAT_A8R8G8B8: return GL_RGBA8;
+ case sw::FORMAT_A8B8G8R8: return GL_RGBA8;
case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
case sw::FORMAT_R5G6B5: return GL_RGB565;
- case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;
- case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;
- case sw::FORMAT_SRGB8_A8: return GL_RGBA8_OES;
- case sw::FORMAT_SRGB8_X8: return GL_RGB8_OES;
+ case sw::FORMAT_X8R8G8B8: return GL_RGB8;
+ case sw::FORMAT_X8B8G8R8: return GL_RGB8;
+ case sw::FORMAT_SRGB8_A8: return GL_RGBA8;
+ case sw::FORMAT_SRGB8_X8: return GL_RGB8;
default:
UNREACHABLE(format);
}
@@ -1962,25 +2122,17 @@
{
switch(format)
{
- case sw::FORMAT_D16:
- case sw::FORMAT_D24X8:
- case sw::FORMAT_D32:
- return GL_DEPTH_COMPONENT16;
- case sw::FORMAT_D24S8:
- return GL_DEPTH24_STENCIL8_OES;
- case sw::FORMAT_D32F:
- case sw::FORMAT_D32F_COMPLEMENTARY:
- case sw::FORMAT_D32F_LOCKABLE:
- return GL_DEPTH_COMPONENT32F;
- case sw::FORMAT_D32FS8_TEXTURE:
- case sw::FORMAT_D32FS8_SHADOW:
- return GL_DEPTH32F_STENCIL8;
- case sw::FORMAT_S8:
- return GL_STENCIL_INDEX8;
+ case sw::FORMAT_D16: return GL_DEPTH_COMPONENT16;
+ case sw::FORMAT_D24X8: return GL_DEPTH_COMPONENT24;
+ case sw::FORMAT_D32: return GL_DEPTH_COMPONENT32_OES;
+ case sw::FORMAT_D24S8: return GL_DEPTH24_STENCIL8_OES;
+ case sw::FORMAT_D32F: return GL_DEPTH_COMPONENT32F;
+ case sw::FORMAT_D32FS8: return GL_DEPTH32F_STENCIL8;
+ case sw::FORMAT_S8: return GL_STENCIL_INDEX8;
default:
UNREACHABLE(format);
}
return GL_DEPTH24_STENCIL8_OES;
}
-}
+}
\ No newline at end of file
diff --git a/src/OpenGL/libGLESv2/utilities.h b/src/OpenGL/libGLESv2/utilities.h
index 53deb98..d8e55aa 100644
--- a/src/OpenGL/libGLESv2/utilities.h
+++ b/src/OpenGL/libGLESv2/utilities.h
@@ -42,22 +42,42 @@
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
- bool IsCompressed(GLenum format, GLint clientVersion);
- GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
- GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats);
- GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);
- GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);
+ bool IsCompressed(GLint intenalformat, GLint clientVersion);
+ bool IsSizedInternalFormat(GLint internalformat); // Not compressed.
+ GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture, GLint clientVersion);
+ GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, Texture *texture, GLint clientVersion);
+ bool ValidateCopyFormats(GLenum textureFormat, GLenum colorbufferFormat);
bool IsValidReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type, GLint clientVersion);
bool IsDepthTexture(GLenum format);
bool IsStencilTexture(GLenum format);
bool IsCubemapTextureTarget(GLenum target);
int CubeFaceIndex(GLenum cubeTarget);
bool IsTextureTarget(GLenum target);
- bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion);
+ GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target, GLint clientVersion);
+ GLsizei GetTypeSize(GLenum type);
- bool IsColorRenderable(GLenum internalformat, GLint clientVersion, bool isTexture);
- bool IsDepthRenderable(GLenum internalformat, GLint clientVersion);
- bool IsStencilRenderable(GLenum internalformat, GLint clientVersion);
+ bool IsColorRenderable(GLint internalformat, GLint clientVersion);
+ bool IsDepthRenderable(GLint internalformat, GLint clientVersion);
+ bool IsStencilRenderable(GLint internalformat, GLint clientVersion);
+ bool IsMipmappable(GLint internalformat, GLint clientVersion);
+
+ GLuint GetAlphaSize(GLint internalformat);
+ GLuint GetRedSize(GLint internalformat);
+ GLuint GetGreenSize(GLint internalformat);
+ GLuint GetBlueSize(GLint internalformat);
+ GLuint GetDepthSize(GLint internalformat);
+ GLuint GetStencilSize(GLint internalformat);
+
+ GLenum GetColorComponentType(GLint internalformat);
+ GLenum GetComponentType(GLint internalformat, GLenum attachment);
+ bool IsNormalizedInteger(GLint internalformat);
+ bool IsNonNormalizedInteger(GLint internalformat);
+ bool IsFloatFormat(GLint internalformat);
+ bool IsSignedNonNormalizedInteger(GLint internalformat);
+ bool IsUnsignedNonNormalizedInteger(GLint internalformat);
+ GLenum GetColorEncoding(GLint internalformat);
// Parse the base uniform name and array index. Returns the base name of the uniform. outSubscript is
// set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid.
@@ -74,25 +94,17 @@
sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
sw::AddressingMode ConvertTextureWrap(GLenum wrap);
+ sw::CompareFunc ConvertCompareFunc(GLenum compareFunc, GLenum compareMode);
sw::SwizzleType ConvertSwizzleType(GLenum swizzleType);
sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);
sw::MipmapType ConvertMipMapFilter(GLenum minFilter);
sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &swPrimitiveType, int &primitiveCount, int &verticesPerPrimitive);
- sw::Format ConvertRenderbufferFormat(GLenum format);
}
namespace sw2es
{
- GLuint GetAlphaSize(sw::Format colorFormat);
- GLuint GetRedSize(sw::Format colorFormat);
- GLuint GetGreenSize(sw::Format colorFormat);
- GLuint GetBlueSize(sw::Format colorFormat);
- GLuint GetDepthSize(sw::Format depthFormat);
- GLuint GetStencilSize(sw::Format stencilFormat);
- GLenum GetComponentType(sw::Format format, GLenum attachment);
-
GLenum ConvertBackBufferFormat(sw::Format format);
GLenum ConvertDepthStencilFormat(sw::Format format);
}
diff --git a/src/Reactor/Android.mk b/src/Reactor/Android.mk
index 1a4c0ea..fa90a1a 100644
--- a/src/Reactor/Android.mk
+++ b/src/Reactor/Android.mk
@@ -108,7 +108,8 @@
LOCAL_CPPFLAGS := -std=c++11
-LOCAL_CFLAGS += -DLOG_TAG=\"libsubzero\" \
+LOCAL_CFLAGS += \
+ -DLOG_TAG=\"libsubzero\" \
-Wall \
-Werror \
-Wno-error=undefined-var-template \
@@ -116,7 +117,8 @@
-Wno-unused-parameter \
-Wno-implicit-exception-spec-mismatch \
-Wno-overloaded-virtual \
- -Wno-non-virtual-dtor
+ -Wno-non-virtual-dtor \
+ -Wno-unknown-warning-option
ifneq (16,${PLATFORM_SDK_VERSION})
LOCAL_CFLAGS += -Xclang -fuse-init-array
diff --git a/src/Reactor/BUILD.gn b/src/Reactor/BUILD.gn
index aac9de5..b92633d 100644
--- a/src/Reactor/BUILD.gn
+++ b/src/Reactor/BUILD.gn
@@ -17,7 +17,7 @@
declare_args() {
# Currently, Subzero is not used by default
# LLVM is still the default backend
- use_swiftshader_with_subzero = is_win || is_linux || is_chromeos
+ use_swiftshader_with_subzero = is_win || is_linux || is_mac || is_chromeos
}
# Need a separate config to ensure the warnings are added to the end.
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 8abb17a..4db16e0 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -32,10 +32,10 @@
#include "LLVMRoutine.hpp"
#include "LLVMRoutineManager.hpp"
#include "x86.hpp"
-#include "CPUID.hpp"
-#include "Thread.hpp"
-#include "Memory.hpp"
-#include "MutexLock.hpp"
+#include "Common/CPUID.hpp"
+#include "Common/Thread.hpp"
+#include "Common/Memory.hpp"
+#include "Common/MutexLock.hpp"
#include <fstream>
@@ -2791,7 +2791,7 @@
RValue<Short4> RoundShort4(RValue<Float4> cast)
{
RValue<Int4> int4 = RoundInt(cast);
- return As<Short4>(Pack(int4, int4));
+ return As<Short4>(PackSigned(int4, int4));
}
RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
@@ -2824,13 +2824,20 @@
return x86::pmaddwd(x, y);
}
- RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
+ RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y)
{
auto result = x86::packsswb(x, y);
return As<SByte8>(Swizzle(As<Int4>(result), 0x88));
}
+ RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y)
+ {
+ auto result = x86::packuswb(x, y);
+
+ return As<Byte8>(Swizzle(As<Int4>(result), 0x88));
+ }
+
RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
{
int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
@@ -2899,7 +2906,7 @@
if(CPUID::supportsSSE4_1())
{
Int4 int4(Min(cast, Float4(0xFFFF))); // packusdw takes care of 0x0000 saturation
- *this = As<Short4>(Pack(As<UInt4>(int4), As<UInt4>(int4)));
+ *this = As<Short4>(PackUnsigned(int4, int4));
}
else
{
@@ -3093,13 +3100,6 @@
return x86::pavgw(x, y);
}
- RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
- {
- auto result = x86::packuswb(x, y);
-
- return As<Byte8>(Swizzle(As<Int4>(result), 0x88));
- }
-
Type *UShort4::getType()
{
return T(Type_v4i16);
@@ -4786,7 +4786,10 @@
RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
+ // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
+ // Restore the following line when LLVM is updated to a version where this issue is fixed.
+ // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
}
RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
@@ -4799,7 +4802,10 @@
RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
+ // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
+ // Restore the following line when LLVM is updated to a version where this issue is fixed.
+ // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
}
RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
@@ -4812,7 +4818,10 @@
RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
+ // FIXME: An LLVM bug causes SExt(ICmpCC()) to produce 0 or 1 instead of 0 or ~0
+ // Restore the following line when LLVM is updated to a version where this issue is fixed.
+ // return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType())) ^ Int4(0xFFFFFFFF);
}
RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
@@ -4846,11 +4855,16 @@
return x86::cvtps2dq(cast);
}
- RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
+ RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y)
{
return x86::packssdw(x, y);
}
+ RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y)
+ {
+ return x86::packusdw(x, y);
+ }
+
RValue<Int> Extract(RValue<Int4> x, int i)
{
return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
@@ -5180,11 +5194,6 @@
}
}
- RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
- {
- return x86::packusdw(As<Int4>(x), As<Int4>(y));
- }
-
Type *UInt4::getType()
{
return T(llvm::VectorType::get(T(UInt::getType()), 4));
@@ -5791,6 +5800,16 @@
return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
}
+ RValue<Int4> IsInf(RValue<Float4> x)
+ {
+ return CmpEQ(As<Int4>(x) & Int4(0x7FFFFFFF), Int4(0x7F800000));
+ }
+
+ RValue<Int4> IsNan(RValue<Float4> x)
+ {
+ return ~CmpEQ(x, x);
+ }
+
RValue<Float4> Round(RValue<Float4> x)
{
if(CPUID::supportsSSE4_1())
@@ -6205,7 +6224,7 @@
return As<SByte8>(V(::builder->CreateCall2(packsswb, x.value, y.value)));
}
- RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y)
+ RValue<Byte8> packuswb(RValue<Short4> x, RValue<Short4> y)
{
llvm::Function *packuswb = llvm::Intrinsic::getDeclaration(::module, llvm::Intrinsic::x86_sse2_packuswb_128);
diff --git a/src/Reactor/Main.cpp b/src/Reactor/Main.cpp
index 37a006a..81442b9 100644
--- a/src/Reactor/Main.cpp
+++ b/src/Reactor/Main.cpp
@@ -288,6 +288,18 @@
*Pointer<Short4>(out + 16 * (512 + 4)) = UnpackLow(Byte8(1, 2, 3, 4, 5, 6, 7, 8), Byte8(9, 10, 11, 12, 13, 14, 15, 16));
*Pointer<Short4>(out + 16 * (512 + 5)) = UnpackHigh(Byte8(1, 2, 3, 4, 5, 6, 7, 8), Byte8(9, 10, 11, 12, 13, 14, 15, 16));
+ for(int i = 0; i < 256; i++)
+ {
+ *Pointer<Short4>(out + 16 * (512 + 6) + (8 * i)) =
+ Swizzle(Short4(1, 2, 3, 4), i);
+ }
+
+ for(int i = 0; i < 256; i++)
+ {
+ *Pointer<Int4>(out + 16 * (512 + 6 + i) + (8 * 256)) =
+ Swizzle(Int4(1, 2, 3, 4), i);
+ }
+
Return(0);
}
@@ -298,7 +310,7 @@
struct
{
float f[256 + 256 + 2][4];
- int i[4][4];
+ int i[388][4];
} out;
memset(&out, 0, sizeof(out));
@@ -351,6 +363,26 @@
EXPECT_EQ(out.i[3][1], 0x10080F07);
EXPECT_EQ(out.i[3][2], 0x00000000);
EXPECT_EQ(out.i[3][3], 0x00000000);
+
+ for(int i = 0; i < 256; i++)
+ {
+ EXPECT_EQ(out.i[4 + i/2][0 + (i%2) * 2] & 0xFFFF,
+ ((i >> 0) & 0x03) + 1);
+ EXPECT_EQ(out.i[4 + i/2][0 + (i%2) * 2] >> 16,
+ ((i >> 2) & 0x03) + 1);
+ EXPECT_EQ(out.i[4 + i/2][1 + (i%2) * 2] & 0xFFFF,
+ ((i >> 4) & 0x03) + 1);
+ EXPECT_EQ(out.i[4 + i/2][1 + (i%2) * 2] >> 16,
+ ((i >> 6) & 0x03) + 1);
+ }
+
+ for(int i = 0; i < 256; i++)
+ {
+ EXPECT_EQ(out.i[132 + i][0], ((i >> 0) & 0x03) + 1);
+ EXPECT_EQ(out.i[132 + i][1], ((i >> 2) & 0x03) + 1);
+ EXPECT_EQ(out.i[132 + i][2], ((i >> 4) & 0x03) + 1);
+ EXPECT_EQ(out.i[132 + i][3], ((i >> 6) & 0x03) + 1);
+ }
}
}
@@ -451,62 +483,62 @@
if(routine)
{
- int out[10][4];
+ unsigned int out[10][4];
memset(&out, 0, sizeof(out));
int(*callable)(void*) = (int(*)(void*))routine->getEntry();
callable(&out);
- EXPECT_EQ(out[0][0], 0x00000000);
- EXPECT_EQ(out[0][1], 0x00000000);
- EXPECT_EQ(out[0][2], 0x00000000);
- EXPECT_EQ(out[0][3], 0x80000000);
+ EXPECT_EQ(out[0][0], 0x00000000u);
+ EXPECT_EQ(out[0][1], 0x00000000u);
+ EXPECT_EQ(out[0][2], 0x00000000u);
+ EXPECT_EQ(out[0][3], 0x80000000u);
- EXPECT_EQ(out[1][0], 0x3F800000);
- EXPECT_EQ(out[1][1], 0x3F800000);
- EXPECT_EQ(out[1][2], 0x00000000);
- EXPECT_EQ(out[1][3], 0x80000000);
+ EXPECT_EQ(out[1][0], 0x3F800000u);
+ EXPECT_EQ(out[1][1], 0x3F800000u);
+ EXPECT_EQ(out[1][2], 0x00000000u);
+ EXPECT_EQ(out[1][3], 0x80000000u);
- EXPECT_EQ(out[2][0], 0x00000000);
- EXPECT_EQ(out[2][1], 0x00000000);
- EXPECT_EQ(out[2][2], 0xFFFFFFFF);
- EXPECT_EQ(out[2][3], 0x00000000);
+ EXPECT_EQ(out[2][0], 0x00000000u);
+ EXPECT_EQ(out[2][1], 0x00000000u);
+ EXPECT_EQ(out[2][2], 0xFFFFFFFFu);
+ EXPECT_EQ(out[2][3], 0x00000000u);
- EXPECT_EQ(out[3][0], 0x00000001);
- EXPECT_EQ(out[3][1], 0x00000001);
- EXPECT_EQ(out[3][2], 0x00000000);
- EXPECT_EQ(out[3][3], 0x00000000);
+ EXPECT_EQ(out[3][0], 0x00000001u);
+ EXPECT_EQ(out[3][1], 0x00000001u);
+ EXPECT_EQ(out[3][2], 0x00000000u);
+ EXPECT_EQ(out[3][3], 0x00000000u);
- EXPECT_EQ(out[4][0], 0x00000000);
- EXPECT_EQ(out[4][1], 0x00000000);
- EXPECT_EQ(out[4][2], 0x00000000);
- EXPECT_EQ(out[4][3], 0x00000000);
+ EXPECT_EQ(out[4][0], 0x00000000u);
+ EXPECT_EQ(out[4][1], 0x00000000u);
+ EXPECT_EQ(out[4][2], 0x00000000u);
+ EXPECT_EQ(out[4][3], 0x00000000u);
- EXPECT_EQ(out[5][0], 0x00000001);
- EXPECT_EQ(out[5][1], 0x00000001);
- EXPECT_EQ(out[5][2], 0xFFFFFFFF);
- EXPECT_EQ(out[5][3], 0x00000000);
+ EXPECT_EQ(out[5][0], 0x00000001u);
+ EXPECT_EQ(out[5][1], 0x00000001u);
+ EXPECT_EQ(out[5][2], 0xFFFFFFFFu);
+ EXPECT_EQ(out[5][3], 0x00000000u);
- EXPECT_EQ(out[6][0], 0x00000000);
- EXPECT_EQ(out[6][1], 0x0000FFFF);
- EXPECT_EQ(out[6][2], 0x00000000);
- EXPECT_EQ(out[6][3], 0x00000000);
+ EXPECT_EQ(out[6][0], 0x00000000u);
+ EXPECT_EQ(out[6][1], 0x0000FFFFu);
+ EXPECT_EQ(out[6][2], 0x00000000u);
+ EXPECT_EQ(out[6][3], 0x00000000u);
- EXPECT_EQ(out[7][0], 0x00010001);
- EXPECT_EQ(out[7][1], 0x00000000);
- EXPECT_EQ(out[7][2], 0x00000000);
- EXPECT_EQ(out[7][3], 0x00000000);
+ EXPECT_EQ(out[7][0], 0x00010001u);
+ EXPECT_EQ(out[7][1], 0x00000000u);
+ EXPECT_EQ(out[7][2], 0x00000000u);
+ EXPECT_EQ(out[7][3], 0x00000000u);
- EXPECT_EQ(out[8][0], 0x00000000);
- EXPECT_EQ(out[8][1], 0x00000000);
- EXPECT_EQ(out[8][2], 0x00000000);
- EXPECT_EQ(out[8][3], 0x00000000);
+ EXPECT_EQ(out[8][0], 0x00000000u);
+ EXPECT_EQ(out[8][1], 0x00000000u);
+ EXPECT_EQ(out[8][2], 0x00000000u);
+ EXPECT_EQ(out[8][3], 0x00000000u);
- EXPECT_EQ(out[9][0], 0x00010001);
- EXPECT_EQ(out[9][1], 0x0000FFFF);
- EXPECT_EQ(out[9][2], 0x00000000);
- EXPECT_EQ(out[9][3], 0x00000000);
+ EXPECT_EQ(out[9][0], 0x00010001u);
+ EXPECT_EQ(out[9][1], 0x0000FFFFu);
+ EXPECT_EQ(out[9][2], 0x00000000u);
+ EXPECT_EQ(out[9][3], 0x00000000u);
}
}
@@ -541,57 +573,57 @@
if(routine)
{
- int out[10][4];
+ unsigned int out[10][4];
memset(&out, 0, sizeof(out));
int(*callable)(void*) = (int(*)(void*))routine->getEntry();
callable(&out);
- EXPECT_EQ(out[0][0], 0xAAAAAAAA);
- EXPECT_EQ(out[0][1], 0x00000000);
- EXPECT_EQ(out[0][2], 0x00000000);
- EXPECT_EQ(out[0][3], 0x00000000);
+ EXPECT_EQ(out[0][0], 0xAAAAAAAAu);
+ EXPECT_EQ(out[0][1], 0x00000000u);
+ EXPECT_EQ(out[0][2], 0x00000000u);
+ EXPECT_EQ(out[0][3], 0x00000000u);
- EXPECT_EQ(out[1][0], 0x0000AAAA);
- EXPECT_EQ(out[1][1], 0x00000000);
- EXPECT_EQ(out[1][2], 0x00000000);
- EXPECT_EQ(out[1][3], 0x00000000);
+ EXPECT_EQ(out[1][0], 0x0000AAAAu);
+ EXPECT_EQ(out[1][1], 0x00000000u);
+ EXPECT_EQ(out[1][2], 0x00000000u);
+ EXPECT_EQ(out[1][3], 0x00000000u);
- EXPECT_EQ(out[2][0], 0xAAAAAAAA);
- EXPECT_EQ(out[2][1], 0x55555555);
- EXPECT_EQ(out[2][2], 0xFFFFFFFF);
- EXPECT_EQ(out[2][3], 0x00000000);
+ EXPECT_EQ(out[2][0], 0xAAAAAAAAu);
+ EXPECT_EQ(out[2][1], 0x55555555u);
+ EXPECT_EQ(out[2][2], 0xFFFFFFFFu);
+ EXPECT_EQ(out[2][3], 0x00000000u);
- EXPECT_EQ(out[3][0], 0x5555AAAA);
- EXPECT_EQ(out[3][1], 0x0000FFFF);
- EXPECT_EQ(out[3][2], 0x00000000);
- EXPECT_EQ(out[3][3], 0x00000000);
+ EXPECT_EQ(out[3][0], 0x5555AAAAu);
+ EXPECT_EQ(out[3][1], 0x0000FFFFu);
+ EXPECT_EQ(out[3][2], 0x00000000u);
+ EXPECT_EQ(out[3][3], 0x00000000u);
- EXPECT_EQ(out[4][0], 0xAAAAAAAB);
- EXPECT_EQ(out[4][1], 0x00000000);
- EXPECT_EQ(out[4][2], 0x00000000);
- EXPECT_EQ(out[4][3], 0x00000000);
+ EXPECT_EQ(out[4][0], 0xAAAAAAABu);
+ EXPECT_EQ(out[4][1], 0x00000000u);
+ EXPECT_EQ(out[4][2], 0x00000000u);
+ EXPECT_EQ(out[4][3], 0x00000000u);
- EXPECT_EQ(out[5][0], 0x0000AAAB);
- EXPECT_EQ(out[5][1], 0x00000000);
- EXPECT_EQ(out[5][2], 0x00000000);
- EXPECT_EQ(out[5][3], 0x00000000);
+ EXPECT_EQ(out[5][0], 0x0000AAABu);
+ EXPECT_EQ(out[5][1], 0x00000000u);
+ EXPECT_EQ(out[5][2], 0x00000000u);
+ EXPECT_EQ(out[5][3], 0x00000000u);
- EXPECT_EQ(out[6][0], 0xAAAAAAAB);
- EXPECT_EQ(out[6][1], 0x55555556);
- EXPECT_EQ(out[6][2], 0x00000000);
- EXPECT_EQ(out[6][3], 0x00000001);
+ EXPECT_EQ(out[6][0], 0xAAAAAAABu);
+ EXPECT_EQ(out[6][1], 0x55555556u);
+ EXPECT_EQ(out[6][2], 0x00000000u);
+ EXPECT_EQ(out[6][3], 0x00000001u);
- EXPECT_EQ(out[7][0], 0x5556AAAB);
- EXPECT_EQ(out[7][1], 0x00010000);
- EXPECT_EQ(out[7][2], 0x00000000);
- EXPECT_EQ(out[7][3], 0x00000000);
+ EXPECT_EQ(out[7][0], 0x5556AAABu);
+ EXPECT_EQ(out[7][1], 0x00010000u);
+ EXPECT_EQ(out[7][2], 0x00000000u);
+ EXPECT_EQ(out[7][3], 0x00000000u);
- EXPECT_EQ(out[8][0], 0xBF800000);
- EXPECT_EQ(out[8][1], 0x3F800000);
- EXPECT_EQ(out[8][2], 0x80000000);
- EXPECT_EQ(out[8][3], 0x00000000);
+ EXPECT_EQ(out[8][0], 0xBF800000u);
+ EXPECT_EQ(out[8][1], 0x3F800000u);
+ EXPECT_EQ(out[8][2], 0x80000000u);
+ EXPECT_EQ(out[8][3], 0x00000000u);
}
}
@@ -622,38 +654,338 @@
if(routine)
{
- int out[6][4];
+ unsigned int out[6][4];
memset(&out, 0, sizeof(out));
int(*callable)(void*) = (int(*)(void*))routine->getEntry();
callable(&out);
- EXPECT_EQ(out[0][0], 0x00000000);
- EXPECT_EQ(out[0][1], 0xFFFFFFFF);
- EXPECT_EQ(out[0][2], 0xFFFFFFFF);
- EXPECT_EQ(out[0][3], 0xFFFFFFFF);
+ EXPECT_EQ(out[0][0], 0x00000000u);
+ EXPECT_EQ(out[0][1], 0xFFFFFFFFu);
+ EXPECT_EQ(out[0][2], 0xFFFFFFFFu);
+ EXPECT_EQ(out[0][3], 0xFFFFFFFFu);
- EXPECT_EQ(out[1][0], 0x00000000);
- EXPECT_EQ(out[1][1], 0x00000000);
- EXPECT_EQ(out[1][2], 0x00000000);
- EXPECT_EQ(out[1][3], 0xFFFFFFFF);
+ EXPECT_EQ(out[1][0], 0x00000000u);
+ EXPECT_EQ(out[1][1], 0x00000000u);
+ EXPECT_EQ(out[1][2], 0x00000000u);
+ EXPECT_EQ(out[1][3], 0xFFFFFFFFu);
- EXPECT_EQ(out[2][0], 0xFF000000);
- EXPECT_EQ(out[2][1], 0x00000000);
+ EXPECT_EQ(out[2][0], 0xFF000000u);
+ EXPECT_EQ(out[2][1], 0x00000000u);
- EXPECT_EQ(out[3][0], 0xFFFFFFFF);
- EXPECT_EQ(out[3][1], 0xFFFFFFFF);
- EXPECT_EQ(out[3][2], 0xFFFFFFFF);
- EXPECT_EQ(out[3][3], 0xFFFFFFFF);
+ EXPECT_EQ(out[3][0], 0xFFFFFFFFu);
+ EXPECT_EQ(out[3][1], 0xFFFFFFFFu);
+ EXPECT_EQ(out[3][2], 0xFFFFFFFFu);
+ EXPECT_EQ(out[3][3], 0xFFFFFFFFu);
- EXPECT_EQ(out[4][0], 0xFFFFFFFF);
- EXPECT_EQ(out[4][1], 0x00000000);
- EXPECT_EQ(out[4][2], 0x00000000);
- EXPECT_EQ(out[4][3], 0xFFFFFFFF);
+ EXPECT_EQ(out[4][0], 0xFFFFFFFFu);
+ EXPECT_EQ(out[4][1], 0x00000000u);
+ EXPECT_EQ(out[4][2], 0x00000000u);
+ EXPECT_EQ(out[4][3], 0xFFFFFFFFu);
- EXPECT_EQ(out[5][0], 0x00000000);
- EXPECT_EQ(out[5][1], 0xFFFFFFFF);
+ EXPECT_EQ(out[5][0], 0x00000000u);
+ EXPECT_EQ(out[5][1], 0xFFFFFFFFu);
+ }
+ }
+
+ delete routine;
+}
+
+TEST(SubzeroReactorTest, SaturatedAddAndSubtract)
+{
+ Routine *routine = nullptr;
+
+ {
+ Function<Int(Pointer<Byte>)> function;
+ {
+ Pointer<Byte> out = function.Arg<0>();
+
+ *Pointer<Byte8>(out + 8 * 0) =
+ AddSat(Byte8(1, 2, 3, 4, 5, 6, 7, 8),
+ Byte8(7, 6, 5, 4, 3, 2, 1, 0));
+ *Pointer<Byte8>(out + 8 * 1) =
+ AddSat(Byte8(0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE),
+ Byte8(7, 6, 5, 4, 3, 2, 1, 0));
+ *Pointer<Byte8>(out + 8 * 2) =
+ SubSat(Byte8(1, 2, 3, 4, 5, 6, 7, 8),
+ Byte8(7, 6, 5, 4, 3, 2, 1, 0));
+
+ *Pointer<SByte8>(out + 8 * 3) =
+ AddSat(SByte8(1, 2, 3, 4, 5, 6, 7, 8),
+ SByte8(7, 6, 5, 4, 3, 2, 1, 0));
+ *Pointer<SByte8>(out + 8 * 4) =
+ AddSat(SByte8(0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E),
+ SByte8(7, 6, 5, 4, 3, 2, 1, 0));
+ *Pointer<SByte8>(out + 8 * 5) =
+ AddSat(SByte8(0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88),
+ SByte8(-7, -6, -5, -4, -3, -2, -1, -0));
+ *Pointer<SByte8>(out + 8 * 6) =
+ SubSat(SByte8(0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88),
+ SByte8(7, 6, 5, 4, 3, 2, 1, 0));
+
+ *Pointer<Short4>(out + 8 * 7) =
+ AddSat(Short4(1, 2, 3, 4), Short4(3, 2, 1, 0));
+ *Pointer<Short4>(out + 8 * 8) =
+ AddSat(Short4(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFE),
+ Short4(3, 2, 1, 0));
+ *Pointer<Short4>(out + 8 * 9) =
+ AddSat(Short4(0x8001, 0x8002, 0x8003, 0x8004),
+ Short4(-3, -2, -1, -0));
+ *Pointer<Short4>(out + 8 * 10) =
+ SubSat(Short4(0x8001, 0x8002, 0x8003, 0x8004),
+ Short4(3, 2, 1, 0));
+
+ *Pointer<UShort4>(out + 8 * 11) =
+ AddSat(UShort4(1, 2, 3, 4), UShort4(3, 2, 1, 0));
+ *Pointer<UShort4>(out + 8 * 12) =
+ AddSat(UShort4(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE),
+ UShort4(3, 2, 1, 0));
+ *Pointer<UShort4>(out + 8 * 13) =
+ SubSat(UShort4(1, 2, 3, 4), UShort4(3, 2, 1, 0));
+
+ Return(0);
+ }
+
+ routine = function(L"one");
+
+ if(routine)
+ {
+ unsigned int out[14][2];
+
+ memset(&out, 0, sizeof(out));
+
+ int(*callable)(void*) = (int(*)(void*))routine->getEntry();
+ callable(&out);
+
+ EXPECT_EQ(out[0][0], 0x08080808u);
+ EXPECT_EQ(out[0][1], 0x08080808u);
+
+ EXPECT_EQ(out[1][0], 0xFFFFFFFFu);
+ EXPECT_EQ(out[1][1], 0xFEFFFFFFu);
+
+ EXPECT_EQ(out[2][0], 0x00000000u);
+ EXPECT_EQ(out[2][1], 0x08060402u);
+
+ EXPECT_EQ(out[3][0], 0x08080808u);
+ EXPECT_EQ(out[3][1], 0x08080808u);
+
+ EXPECT_EQ(out[4][0], 0x7F7F7F7Fu);
+ EXPECT_EQ(out[4][1], 0x7E7F7F7Fu);
+
+ EXPECT_EQ(out[5][0], 0x80808080u);
+ EXPECT_EQ(out[5][1], 0x88868482u);
+
+ EXPECT_EQ(out[6][0], 0x80808080u);
+ EXPECT_EQ(out[6][1], 0x88868482u);
+
+ EXPECT_EQ(out[7][0], 0x00040004u);
+ EXPECT_EQ(out[7][1], 0x00040004u);
+
+ EXPECT_EQ(out[8][0], 0x7FFF7FFFu);
+ EXPECT_EQ(out[8][1], 0x7FFE7FFFu);
+
+ EXPECT_EQ(out[9][0], 0x80008000u);
+ EXPECT_EQ(out[9][1], 0x80048002u);
+
+ EXPECT_EQ(out[10][0], 0x80008000u);
+ EXPECT_EQ(out[10][1], 0x80048002u);
+
+ EXPECT_EQ(out[11][0], 0x00040004u);
+ EXPECT_EQ(out[11][1], 0x00040004u);
+
+ EXPECT_EQ(out[12][0], 0xFFFFFFFFu);
+ EXPECT_EQ(out[12][1], 0xFFFEFFFFu);
+
+ EXPECT_EQ(out[13][0], 0x00000000u);
+ EXPECT_EQ(out[13][1], 0x00040002u);
+ }
+ }
+
+ delete routine;
+}
+
+TEST(SubzeroReactorTest, Unpack)
+{
+ Routine *routine = nullptr;
+
+ {
+ Function<Int(Pointer<Byte>,Pointer<Byte>)> function;
+ {
+ Pointer<Byte> in = function.Arg<0>();
+ Pointer<Byte> out = function.Arg<1>();
+
+ Byte4 test_byte_a = *Pointer<Byte4>(in + 4 * 0);
+ Byte4 test_byte_b = *Pointer<Byte4>(in + 4 * 1);
+
+ *Pointer<Short4>(out + 8 * 0) =
+ Unpack(test_byte_a, test_byte_b);
+
+ *Pointer<Short4>(out + 8 * 1) = Unpack(test_byte_a);
+
+ Return(0);
+ }
+
+ routine = function(L"one");
+
+ if(routine)
+ {
+ unsigned int in[1][2];
+ unsigned int out[2][2];
+
+ memset(&out, 0, sizeof(out));
+
+ in[0][0] = 0xABCDEF12u;
+ in[0][1] = 0x34567890u;
+
+ int(*callable)(void*,void*) = (int(*)(void*,void*))routine->getEntry();
+ callable(&in, &out);
+
+ EXPECT_EQ(out[0][0], 0x78EF9012u);
+ EXPECT_EQ(out[0][1], 0x34AB56CDu);
+
+ EXPECT_EQ(out[1][0], 0xEFEF1212u);
+ EXPECT_EQ(out[1][1], 0xABABCDCDu);
+ }
+ }
+
+ delete routine;
+}
+
+TEST(SubzeroReactorTest, Pack)
+{
+ Routine *routine = nullptr;
+
+ {
+ Function<Int(Pointer<Byte>)> function;
+ {
+ Pointer<Byte> out = function.Arg<0>();
+
+ *Pointer<SByte8>(out + 8 * 0) =
+ PackSigned(Short4(-1, -2, 1, 2),
+ Short4(3, 4, -3, -4));
+
+ *Pointer<Byte8>(out + 8 * 1) =
+ PackUnsigned(Short4(-1, -2, 1, 2),
+ Short4(3, 4, -3, -4));
+
+ *Pointer<Short8>(out + 8 * 2) =
+ PackSigned(Int4(-1, -2, 1, 2),
+ Int4(3, 4, -3, -4));
+
+ *Pointer<UShort8>(out + 8 * 4) =
+ PackUnsigned(Int4(-1, -2, 1, 2),
+ Int4(3, 4, -3, -4));
+
+ Return(0);
+ }
+
+ routine = function(L"one");
+
+ if(routine)
+ {
+ unsigned int out[6][2];
+
+ memset(&out, 0, sizeof(out));
+
+ int(*callable)(void*) = (int(*)(void*))routine->getEntry();
+ callable(&out);
+
+ EXPECT_EQ(out[0][0], 0x0201FEFFu);
+ EXPECT_EQ(out[0][1], 0xFCFD0403u);
+
+ EXPECT_EQ(out[1][0], 0x02010000u);
+ EXPECT_EQ(out[1][1], 0x00000403u);
+
+ EXPECT_EQ(out[2][0], 0xFFFEFFFFu);
+ EXPECT_EQ(out[2][1], 0x00020001u);
+
+ EXPECT_EQ(out[3][0], 0x00040003u);
+ EXPECT_EQ(out[3][1], 0xFFFCFFFDu);
+
+ EXPECT_EQ(out[4][0], 0x00000000u);
+ EXPECT_EQ(out[4][1], 0x00020001u);
+
+ EXPECT_EQ(out[5][0], 0x00040003u);
+ EXPECT_EQ(out[5][1], 0x00000000u);
+ }
+ }
+
+ delete routine;
+}
+
+TEST(SubzeroReactorTest, MulHigh)
+{
+ Routine *routine = nullptr;
+
+ {
+ Function<Int(Pointer<Byte>)> function;
+ {
+ Pointer<Byte> out = function.Arg<0>();
+
+ *Pointer<Short4>(out + 8 * 0) =
+ MulHigh(Short4(0x1aa, 0x2dd, 0x3ee, 0xF422),
+ Short4(0x1bb, 0x2cc, 0x3ff, 0xF411));
+ *Pointer<UShort4>(out + 8 * 1) =
+ MulHigh(UShort4(0x1aa, 0x2dd, 0x3ee, 0xF422),
+ UShort4(0x1bb, 0x2cc, 0x3ff, 0xF411));
+
+ // (U)Short8 variants are mentioned but unimplemented
+ Return(0);
+ }
+
+ routine = function(L"one");
+
+ if(routine)
+ {
+ unsigned int out[2][2];
+
+ memset(&out, 0, sizeof(out));
+
+ int(*callable)(void*) = (int(*)(void*))routine->getEntry();
+ callable(&out);
+
+ EXPECT_EQ(out[0][0], 0x00080002u);
+ EXPECT_EQ(out[0][1], 0x008D000fu);
+
+ EXPECT_EQ(out[1][0], 0x00080002u);
+ EXPECT_EQ(out[1][1], 0xe8C0000Fu);
+ }
+ }
+
+ delete routine;
+}
+
+TEST(SubzeroReactorTest, MulAdd)
+{
+ Routine *routine = nullptr;
+
+ {
+ Function<Int(Pointer<Byte>)> function;
+ {
+ Pointer<Byte> out = function.Arg<0>();
+
+ *Pointer<Int2>(out + 8 * 0) =
+ MulAdd(Short4(0x1aa, 0x2dd, 0x3ee, 0xF422),
+ Short4(0x1bb, 0x2cc, 0x3ff, 0xF411));
+
+ // (U)Short8 variant is mentioned but unimplemented
+ Return(0);
+ }
+
+ routine = function(L"one");
+
+ if(routine)
+ {
+ unsigned int out[1][2];
+
+ memset(&out, 0, sizeof(out));
+
+ int(*callable)(void*) = (int(*)(void*))routine->getEntry();
+ callable(&out);
+
+ EXPECT_EQ(out[0][0], 0x000AE34Au);
+ EXPECT_EQ(out[0][1], 0x009D5254u);
}
}
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 3f9fb3d4..a6d364f 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -797,7 +797,8 @@
RValue<Short4> SubSat(RValue<Short4> x, RValue<Short4> y);
RValue<Short4> MulHigh(RValue<Short4> x, RValue<Short4> y);
RValue<Int2> MulAdd(RValue<Short4> x, RValue<Short4> y);
- RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y);
+ RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y);
+ RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y);
RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y);
RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y);
RValue<Short4> Swizzle(RValue<Short4> x, unsigned char select);
@@ -866,7 +867,6 @@
RValue<UShort4> SubSat(RValue<UShort4> x, RValue<UShort4> y);
RValue<UShort4> MulHigh(RValue<UShort4> x, RValue<UShort4> y);
RValue<UShort4> Average(RValue<UShort4> x, RValue<UShort4> y);
- RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y);
class Short8 : public LValue<Short8>
{
@@ -1831,7 +1831,8 @@
RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y);
RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y);
RValue<Int4> RoundInt(RValue<Float4> cast);
- RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y);
+ RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y);
+ RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y);
RValue<Int> Extract(RValue<Int4> val, int i);
RValue<Int4> Insert(RValue<Int4> val, RValue<Int> element, int i);
RValue<Int> SignMask(RValue<Int4> x);
@@ -1911,7 +1912,6 @@
RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y);
RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y);
// RValue<UInt4> RoundInt(RValue<Float4> cast);
- RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y);
class Float : public LValue<Float>
{
@@ -2110,6 +2110,8 @@
RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y);
RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y);
RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y);
+ RValue<Int4> IsInf(RValue<Float4> x);
+ RValue<Int4> IsNan(RValue<Float4> x);
RValue<Float4> Round(RValue<Float4> x);
RValue<Float4> Trunc(RValue<Float4> x);
RValue<Float4> Frac(RValue<Float4> x);
diff --git a/src/Reactor/Reactor.vcxproj b/src/Reactor/Reactor.vcxproj
index 744614c..6bd1813 100644
--- a/src/Reactor/Reactor.vcxproj
+++ b/src/Reactor/Reactor.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -30,43 +30,44 @@
<ProjectGuid>{28FD076D-10B5-4BD8-A4CF-F44C7002A803}</ProjectGuid>
<RootNamespace>Reactor</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -109,7 +110,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_HAS_EXCEPTIONS=0;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -122,6 +123,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<ExceptionHandling>false</ExceptionHandling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
@@ -133,7 +135,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_HAS_EXCEPTIONS=0;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling>false</ExceptionHandling>
@@ -147,6 +149,7 @@
<OmitFramePointers>false</OmitFramePointers>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
@@ -160,7 +163,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -176,6 +179,7 @@
<FloatingPointExceptions>false</FloatingPointExceptions>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
@@ -189,7 +193,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -203,6 +207,7 @@
<StringPooling>true</StringPooling>
<FloatingPointExceptions>false</FloatingPointExceptions>
<TreatWarningAsError>true</TreatWarningAsError>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
@@ -219,7 +224,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -234,6 +239,7 @@
<FloatingPointExceptions>false</FloatingPointExceptions>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
@@ -250,7 +256,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;..\Common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;..\..\third_party\LLVM\include;..\..\third_party\LLVM\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -264,6 +270,7 @@
<StringPooling>true</StringPooling>
<FloatingPointExceptions>false</FloatingPointExceptions>
<TreatWarningAsError>true</TreatWarningAsError>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<ProjectReference>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
diff --git a/src/Reactor/Subzero.vcxproj b/src/Reactor/Subzero.vcxproj
index 34e87f6..1662e0f 100644
--- a/src/Reactor/Subzero.vcxproj
+++ b/src/Reactor/Subzero.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -22,32 +22,32 @@
<ProjectGuid>{0EB31AEC-B020-46AB-BA05-730F6D01C29B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>Subzero</RootNamespace>
- <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
@@ -91,6 +91,7 @@
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ForcedIncludeFiles>src/IceTypes.h</ForcedIncludeFiles>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -109,6 +110,7 @@
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ForcedIncludeFiles>src/IceTypes.h</ForcedIncludeFiles>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -129,6 +131,7 @@
<ForcedIncludeFiles>src/IceTypes.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -155,6 +158,7 @@
<ForcedIncludeFiles>src/IceTypes.h</ForcedIncludeFiles>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
diff --git a/src/Reactor/SubzeroLLVMDependencies.vcxproj b/src/Reactor/SubzeroLLVMDependencies.vcxproj
index c424b47..87502e9 100644
--- a/src/Reactor/SubzeroLLVMDependencies.vcxproj
+++ b/src/Reactor/SubzeroLLVMDependencies.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,32 +21,32 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{E3BBD7DA-45C1-43EF-9C87-3F411031BDE4}</ProjectGuid>
<RootNamespace>SubzeroLLVMDependencies</RootNamespace>
- <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
@@ -78,6 +78,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -89,6 +90,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -102,6 +104,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -119,6 +122,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index a770981..66099ec 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -119,7 +119,7 @@
const bool CPUID::ARM = CPUID::detectARM();
const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
- const bool emulateIntrinsics = CPUID::ARM;
+ const bool emulateIntrinsics = false;
const bool emulateMismatchedBitCast = CPUID::ARM;
}
@@ -709,7 +709,7 @@
static Value *createArithmetic(Ice::InstArithmetic::OpKind op, Value *lhs, Value *rhs)
{
- assert(lhs->getType() == rhs->getType() || (llvm::isa<Ice::Constant>(rhs) && (op == Ice::InstArithmetic::Shl || Ice::InstArithmetic::Lshr || Ice::InstArithmetic::Ashr)));
+ assert(lhs->getType() == rhs->getType() || llvm::isa<Ice::Constant>(rhs));
bool swapOperands = llvm::isa<Ice::Constant>(lhs) && isCommutative(op);
@@ -843,7 +843,7 @@
int valueType = (int)reinterpret_cast<intptr_t>(type);
Ice::Variable *result = ::function->makeVariable(T(type));
- if(valueType & EmulatedBits)
+ if((valueType & EmulatedBits) && (align != 0)) // Narrow vector not stored on stack.
{
if(emulateIntrinsics)
{
@@ -896,7 +896,7 @@
{
int valueType = (int)reinterpret_cast<intptr_t>(type);
- if(valueType & EmulatedBits)
+ if((valueType & EmulatedBits) && (align != 0)) // Narrow vector not stored on stack.
{
if(emulateIntrinsics)
{
@@ -941,7 +941,7 @@
}
else
{
- assert(T(value->getType()) == type);
+ assert(value->getType() == T(type));
auto store = Ice::InstStore::create(::function, value, ptr, align);
::basicBlock->appendInst(store);
@@ -2716,9 +2716,9 @@
return RValue<Byte8>(Nucleus::createInsertElement(val.value, element.value, i));
}
- RValue<Byte> Saturate(RValue<UShort> x)
+ RValue<Byte> SaturateUnsigned(RValue<Short> x)
{
- return Byte(IfThenElse(Int(x) > 0xFF, Int(0xFF), Int(x)));
+ return Byte(IfThenElse(Int(x) > 0xFF, Int(0xFF), IfThenElse(Int(x) < 0, Int(0), Int(x))));
}
RValue<Byte8> AddSat(RValue<Byte8> x, RValue<Byte8> y)
@@ -2726,14 +2726,14 @@
if(emulateIntrinsics)
{
Byte8 result;
- result = Insert(result, Saturate(UShort(Int(Extract(x, 0))) + UShort(Int(Extract(y, 0)))), 0);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 1))) + UShort(Int(Extract(y, 1)))), 1);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 2))) + UShort(Int(Extract(y, 2)))), 2);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 3))) + UShort(Int(Extract(y, 3)))), 3);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 4))) + UShort(Int(Extract(y, 4)))), 4);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 5))) + UShort(Int(Extract(y, 5)))), 5);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 6))) + UShort(Int(Extract(y, 6)))), 6);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 7))) + UShort(Int(Extract(y, 7)))), 7);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
return result;
}
@@ -2756,14 +2756,14 @@
if(emulateIntrinsics)
{
Byte8 result;
- result = Insert(result, Saturate(UShort(Int(Extract(x, 0))) - UShort(Int(Extract(y, 0)))), 0);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 1))) - UShort(Int(Extract(y, 1)))), 1);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 2))) - UShort(Int(Extract(y, 2)))), 2);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 3))) - UShort(Int(Extract(y, 3)))), 3);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 4))) - UShort(Int(Extract(y, 4)))), 4);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 5))) - UShort(Int(Extract(y, 5)))), 5);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 6))) - UShort(Int(Extract(y, 6)))), 6);
- result = Insert(result, Saturate(UShort(Int(Extract(x, 7))) - UShort(Int(Extract(y, 7)))), 7);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
+ result = Insert(result, SaturateUnsigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
return result;
}
@@ -2847,7 +2847,7 @@
RValue<Int> SignMask(RValue<Byte8> x)
{
- if(emulateIntrinsics)
+ if(emulateIntrinsics || CPUID::ARM)
{
Byte8 xx = As<Byte8>(As<SByte8>(x) >> 7) & Byte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
return Int(Extract(xx, 0)) | Int(Extract(xx, 1)) | Int(Extract(xx, 2)) | Int(Extract(xx, 3)) | Int(Extract(xx, 4)) | Int(Extract(xx, 5)) | Int(Extract(xx, 6)) | Int(Extract(xx, 7));
@@ -3043,7 +3043,7 @@
return RValue<SByte8>(Nucleus::createNot(val.value));
}
- RValue<SByte> Saturate(RValue<Short> x)
+ RValue<SByte> SaturateSigned(RValue<Short> x)
{
return SByte(IfThenElse(Int(x) > 0x7F, Int(0x7F), IfThenElse(Int(x) < -0x80, Int(0x80), Int(x))));
}
@@ -3053,14 +3053,14 @@
if(emulateIntrinsics)
{
SByte8 result;
- result = Insert(result, Saturate(Short(Int(Extract(x, 0))) + Short(Int(Extract(y, 0)))), 0);
- result = Insert(result, Saturate(Short(Int(Extract(x, 1))) + Short(Int(Extract(y, 1)))), 1);
- result = Insert(result, Saturate(Short(Int(Extract(x, 2))) + Short(Int(Extract(y, 2)))), 2);
- result = Insert(result, Saturate(Short(Int(Extract(x, 3))) + Short(Int(Extract(y, 3)))), 3);
- result = Insert(result, Saturate(Short(Int(Extract(x, 4))) + Short(Int(Extract(y, 4)))), 4);
- result = Insert(result, Saturate(Short(Int(Extract(x, 5))) + Short(Int(Extract(y, 5)))), 5);
- result = Insert(result, Saturate(Short(Int(Extract(x, 6))) + Short(Int(Extract(y, 6)))), 6);
- result = Insert(result, Saturate(Short(Int(Extract(x, 7))) + Short(Int(Extract(y, 7)))), 7);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) + Int(Extract(y, 0)))), 0);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) + Int(Extract(y, 1)))), 1);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) + Int(Extract(y, 2)))), 2);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) + Int(Extract(y, 3)))), 3);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) + Int(Extract(y, 4)))), 4);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) + Int(Extract(y, 5)))), 5);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) + Int(Extract(y, 6)))), 6);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) + Int(Extract(y, 7)))), 7);
return result;
}
@@ -3083,14 +3083,14 @@
if(emulateIntrinsics)
{
SByte8 result;
- result = Insert(result, Saturate(Short(Int(Extract(x, 0))) - Short(Int(Extract(y, 0)))), 0);
- result = Insert(result, Saturate(Short(Int(Extract(x, 1))) - Short(Int(Extract(y, 1)))), 1);
- result = Insert(result, Saturate(Short(Int(Extract(x, 2))) - Short(Int(Extract(y, 2)))), 2);
- result = Insert(result, Saturate(Short(Int(Extract(x, 3))) - Short(Int(Extract(y, 3)))), 3);
- result = Insert(result, Saturate(Short(Int(Extract(x, 4))) - Short(Int(Extract(y, 4)))), 4);
- result = Insert(result, Saturate(Short(Int(Extract(x, 5))) - Short(Int(Extract(y, 5)))), 5);
- result = Insert(result, Saturate(Short(Int(Extract(x, 6))) - Short(Int(Extract(y, 6)))), 6);
- result = Insert(result, Saturate(Short(Int(Extract(x, 7))) - Short(Int(Extract(y, 7)))), 7);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 0)) - Int(Extract(y, 0)))), 0);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 1)) - Int(Extract(y, 1)))), 1);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 2)) - Int(Extract(y, 2)))), 2);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 3)) - Int(Extract(y, 3)))), 3);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 4)) - Int(Extract(y, 4)))), 4);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 5)) - Int(Extract(y, 5)))), 5);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 6)) - Int(Extract(y, 6)))), 6);
+ result = Insert(result, SaturateSigned(Short(Int(Extract(x, 7)) - Int(Extract(y, 7)))), 7);
return result;
}
@@ -3123,7 +3123,7 @@
RValue<Int> SignMask(RValue<SByte8> x)
{
- if(emulateIntrinsics)
+ if(emulateIntrinsics || CPUID::ARM)
{
SByte8 xx = (x >> 7) & SByte8(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
return Int(Extract(xx, 0)) | Int(Extract(xx, 1)) | Int(Extract(xx, 2)) | Int(Extract(xx, 3)) | Int(Extract(xx, 4)) | Int(Extract(xx, 5)) | Int(Extract(xx, 6)) | Int(Extract(xx, 7));
@@ -3491,7 +3491,7 @@
RValue<Short4> RoundShort4(RValue<Float4> cast)
{
RValue<Int4> int4 = RoundInt(cast);
- return As<Short4>(Pack(int4, int4));
+ return As<Short4>(PackSigned(int4, int4));
}
RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
@@ -3520,7 +3520,7 @@
return RValue<Short4>(V(result));
}
- RValue<Short> Saturate(RValue<Int> x)
+ RValue<Short> SaturateSigned(RValue<Int> x)
{
return Short(IfThenElse(x > 0x7FFF, Int(0x7FFF), IfThenElse(x < -0x8000, Int(0x8000), x)));
}
@@ -3530,10 +3530,10 @@
if(emulateIntrinsics)
{
Short4 result;
- result = Insert(result, Saturate(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
- result = Insert(result, Saturate(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
- result = Insert(result, Saturate(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
- result = Insert(result, Saturate(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
+ result = Insert(result, SaturateSigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
+ result = Insert(result, SaturateSigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
+ result = Insert(result, SaturateSigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
+ result = Insert(result, SaturateSigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
return result;
}
@@ -3556,10 +3556,10 @@
if(emulateIntrinsics)
{
Short4 result;
- result = Insert(result, Saturate(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
- result = Insert(result, Saturate(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
- result = Insert(result, Saturate(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
- result = Insert(result, Saturate(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
+ result = Insert(result, SaturateSigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
+ result = Insert(result, SaturateSigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
+ result = Insert(result, SaturateSigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
+ result = Insert(result, SaturateSigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
return result;
}
@@ -3627,19 +3627,19 @@
}
}
- RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
+ RValue<SByte8> PackSigned(RValue<Short4> x, RValue<Short4> y)
{
if(emulateIntrinsics)
{
SByte8 result;
- result = Insert(result, Saturate(Extract(x, 0)), 0);
- result = Insert(result, Saturate(Extract(x, 1)), 1);
- result = Insert(result, Saturate(Extract(x, 2)), 2);
- result = Insert(result, Saturate(Extract(x, 3)), 3);
- result = Insert(result, Saturate(Extract(y, 0)), 4);
- result = Insert(result, Saturate(Extract(y, 1)), 5);
- result = Insert(result, Saturate(Extract(y, 2)), 6);
- result = Insert(result, Saturate(Extract(y, 3)), 7);
+ result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
+ result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
+ result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
+ result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
+ result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
+ result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
+ result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
+ result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
return result;
}
@@ -3657,6 +3657,36 @@
}
}
+ RValue<Byte8> PackUnsigned(RValue<Short4> x, RValue<Short4> y)
+ {
+ if(emulateIntrinsics)
+ {
+ Byte8 result;
+ result = Insert(result, SaturateUnsigned(Extract(x, 0)), 0);
+ result = Insert(result, SaturateUnsigned(Extract(x, 1)), 1);
+ result = Insert(result, SaturateUnsigned(Extract(x, 2)), 2);
+ result = Insert(result, SaturateUnsigned(Extract(x, 3)), 3);
+ result = Insert(result, SaturateUnsigned(Extract(y, 0)), 4);
+ result = Insert(result, SaturateUnsigned(Extract(y, 1)), 5);
+ result = Insert(result, SaturateUnsigned(Extract(y, 2)), 6);
+ result = Insert(result, SaturateUnsigned(Extract(y, 3)), 7);
+
+ return result;
+ }
+ else
+ {
+ Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
+ const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
+ auto target = ::context->getConstantUndef(Ice::IceType_i32);
+ auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
+ pack->addArg(x.value);
+ pack->addArg(y.value);
+ ::basicBlock->appendInst(pack);
+
+ return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
+ }
+ }
+
RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
{
int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11}; // Real type is v8i16
@@ -3724,8 +3754,16 @@
{
if(CPUID::SSE4_1)
{
- Int4 int4(Min(cast, Float4(0xFFFF))); // packusdw takes care of 0x0000 saturation
- *this = As<Short4>(Pack(As<UInt4>(int4), As<UInt4>(int4)));
+ // x86 produces 0x80000000 on 32-bit integer overflow/underflow.
+ // PackUnsigned takes care of 0x0000 saturation.
+ Int4 int4(Min(cast, Float4(0xFFFF)));
+ *this = As<UShort4>(PackUnsigned(int4, int4));
+ }
+ else if(CPUID::ARM)
+ {
+ // ARM saturates the 32-bit integer result on overflow/undeflow.
+ Int4 int4(cast);
+ *this = As<UShort4>(PackUnsigned(int4, int4));
}
else
{
@@ -3947,7 +3985,7 @@
return RValue<UShort4>(V(result));
}
- RValue<UShort> SaturateUShort(RValue<Int> x)
+ RValue<UShort> SaturateUnsigned(RValue<Int> x)
{
return UShort(IfThenElse(x > 0xFFFF, Int(0xFFFF), IfThenElse(x < 0, Int(0), x)));
}
@@ -3957,10 +3995,10 @@
if(emulateIntrinsics)
{
UShort4 result;
- result = Insert(result, SaturateUShort(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
- result = Insert(result, SaturateUShort(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
- result = Insert(result, SaturateUShort(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
- result = Insert(result, SaturateUShort(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
+ result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) + Int(Extract(y, 0))), 0);
+ result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) + Int(Extract(y, 1))), 1);
+ result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) + Int(Extract(y, 2))), 2);
+ result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) + Int(Extract(y, 3))), 3);
return result;
}
@@ -3983,10 +4021,10 @@
if(emulateIntrinsics)
{
UShort4 result;
- result = Insert(result, SaturateUShort(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
- result = Insert(result, SaturateUShort(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
- result = Insert(result, SaturateUShort(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
- result = Insert(result, SaturateUShort(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
+ result = Insert(result, SaturateUnsigned(Int(Extract(x, 0)) - Int(Extract(y, 0))), 0);
+ result = Insert(result, SaturateUnsigned(Int(Extract(x, 1)) - Int(Extract(y, 1))), 1);
+ result = Insert(result, SaturateUnsigned(Int(Extract(x, 2)) - Int(Extract(y, 2))), 2);
+ result = Insert(result, SaturateUnsigned(Int(Extract(x, 3)) - Int(Extract(y, 3))), 3);
return result;
}
@@ -4035,36 +4073,6 @@
assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
}
- RValue<Byte8> Pack(RValue<UShort4> x, RValue<UShort4> y)
- {
- if(emulateIntrinsics)
- {
- Byte8 result;
- result = Insert(result, Saturate(Extract(x, 0)), 0);
- result = Insert(result, Saturate(Extract(x, 1)), 1);
- result = Insert(result, Saturate(Extract(x, 2)), 2);
- result = Insert(result, Saturate(Extract(x, 3)), 3);
- result = Insert(result, Saturate(Extract(y, 0)), 4);
- result = Insert(result, Saturate(Extract(y, 1)), 5);
- result = Insert(result, Saturate(Extract(y, 2)), 6);
- result = Insert(result, Saturate(Extract(y, 3)), 7);
-
- return result;
- }
- else
- {
- Ice::Variable *result = ::function->makeVariable(Ice::IceType_v16i8);
- const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
- auto target = ::context->getConstantUndef(Ice::IceType_i32);
- auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
- pack->addArg(x.value);
- pack->addArg(y.value);
- ::basicBlock->appendInst(pack);
-
- return As<Byte8>(Swizzle(As<Int4>(V(result)), 0x88));
- }
- }
-
Type *UShort4::getType()
{
return T(Type_v4i16);
@@ -4670,7 +4678,7 @@
RValue<Int> RoundInt(RValue<Float> cast)
{
- if(emulateIntrinsics)
+ if(emulateIntrinsics || CPUID::ARM)
{
// Push the fractional part off the mantissa. Accurate up to +/-2^22.
return Int((cast + Float(0x00C00000)) - Float(0x00C00000));
@@ -5913,7 +5921,7 @@
RValue<Int4> RoundInt(RValue<Float4> cast)
{
- if(emulateIntrinsics)
+ if(emulateIntrinsics || CPUID::ARM)
{
// Push the fractional part off the mantissa. Accurate up to +/-2^22.
return Int4((cast + Float4(0x00C00000)) - Float4(0x00C00000));
@@ -5931,19 +5939,19 @@
}
}
- RValue<Short8> Pack(RValue<Int4> x, RValue<Int4> y)
+ RValue<Short8> PackSigned(RValue<Int4> x, RValue<Int4> y)
{
if(emulateIntrinsics)
{
Short8 result;
- result = Insert(result, Saturate(Extract(x, 0)), 0);
- result = Insert(result, Saturate(Extract(x, 1)), 1);
- result = Insert(result, Saturate(Extract(x, 2)), 2);
- result = Insert(result, Saturate(Extract(x, 3)), 3);
- result = Insert(result, Saturate(Extract(y, 0)), 4);
- result = Insert(result, Saturate(Extract(y, 1)), 5);
- result = Insert(result, Saturate(Extract(y, 2)), 6);
- result = Insert(result, Saturate(Extract(y, 3)), 7);
+ result = Insert(result, SaturateSigned(Extract(x, 0)), 0);
+ result = Insert(result, SaturateSigned(Extract(x, 1)), 1);
+ result = Insert(result, SaturateSigned(Extract(x, 2)), 2);
+ result = Insert(result, SaturateSigned(Extract(x, 3)), 3);
+ result = Insert(result, SaturateSigned(Extract(y, 0)), 4);
+ result = Insert(result, SaturateSigned(Extract(y, 1)), 5);
+ result = Insert(result, SaturateSigned(Extract(y, 2)), 6);
+ result = Insert(result, SaturateSigned(Extract(y, 3)), 7);
return result;
}
@@ -5961,6 +5969,32 @@
}
}
+ RValue<UShort8> PackUnsigned(RValue<Int4> x, RValue<Int4> y)
+ {
+ if(emulateIntrinsics || !(CPUID::SSE4_1 || CPUID::ARM))
+ {
+ RValue<Int4> sx = As<Int4>(x);
+ RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
+
+ RValue<Int4> sy = As<Int4>(y);
+ RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
+
+ return As<UShort8>(PackSigned(bx, by) + Short8(0x8000u));
+ }
+ else
+ {
+ Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
+ const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
+ auto target = ::context->getConstantUndef(Ice::IceType_i32);
+ auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
+ pack->addArg(x.value);
+ pack->addArg(y.value);
+ ::basicBlock->appendInst(pack);
+
+ return RValue<UShort8>(V(result));
+ }
+ }
+
RValue<Int> Extract(RValue<Int4> x, int i)
{
return RValue<Int>(Nucleus::createExtractElement(x.value, Int::getType(), i));
@@ -5973,7 +6007,7 @@
RValue<Int> SignMask(RValue<Int4> x)
{
- if(emulateIntrinsics)
+ if(emulateIntrinsics || CPUID::ARM)
{
Int4 xx = (x >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
@@ -6329,32 +6363,6 @@
return RValue<UInt4>(V(result));
}
- RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
- {
- if(CPUID::SSE4_1)
- {
- Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
- const Ice::Intrinsics::IntrinsicInfo intrinsic = {Ice::Intrinsics::VectorPackUnsigned, Ice::Intrinsics::SideEffects_F, Ice::Intrinsics::ReturnsTwice_F, Ice::Intrinsics::MemoryWrite_F};
- auto target = ::context->getConstantUndef(Ice::IceType_i32);
- auto pack = Ice::InstIntrinsicCall::create(::function, 2, result, target, intrinsic);
- pack->addArg(x.value);
- pack->addArg(y.value);
- ::basicBlock->appendInst(pack);
-
- return RValue<UShort8>(V(result));
- }
- else
- {
- RValue<Int4> sx = As<Int4>(x);
- RValue<Int4> bx = (sx & ~(sx >> 31)) - Int4(0x8000);
-
- RValue<Int4> sy = As<Int4>(y);
- RValue<Int4> by = (sy & ~(sy >> 31)) - Int4(0x8000);
-
- return As<UShort8>(Pack(bx, by) + Short8(0x8000u));
- }
- }
-
Type *UInt4::getType()
{
return T(Ice::IceType_v4i32);
@@ -6837,7 +6845,7 @@
RValue<Float4> Sqrt(RValue<Float4> x)
{
- if(emulateIntrinsics)
+ if(emulateIntrinsics || CPUID::ARM)
{
Float4 result;
result.x = Sqrt(Float(Float4(x).x));
@@ -6911,7 +6919,7 @@
RValue<Int> SignMask(RValue<Float4> x)
{
- if(emulateIntrinsics)
+ if(emulateIntrinsics || CPUID::ARM)
{
Int4 xx = (As<Int4>(x) >> 31) & Int4(0x00000001, 0x00000002, 0x00000004, 0x00000008);
return Extract(xx, 0) | Extract(xx, 1) | Extract(xx, 2) | Extract(xx, 3);
@@ -6959,9 +6967,19 @@
return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
}
+ RValue<Int4> IsInf(RValue<Float4> x)
+ {
+ return CmpEQ(As<Int4>(x) & Int4(0x7FFFFFFF), Int4(0x7F800000));
+ }
+
+ RValue<Int4> IsNan(RValue<Float4> x)
+ {
+ return ~CmpEQ(x, x);
+ }
+
RValue<Float4> Round(RValue<Float4> x)
{
- if(emulateIntrinsics)
+ if(emulateIntrinsics || CPUID::ARM)
{
// Push the fractional part off the mantissa. Accurate up to +/-2^22.
return (x + Float4(0x00C00000)) - Float4(0x00C00000);
diff --git a/src/Reactor/SubzeroTest.vcxproj b/src/Reactor/SubzeroTest.vcxproj
index 4428ece..febe352 100644
--- a/src/Reactor/SubzeroTest.vcxproj
+++ b/src/Reactor/SubzeroTest.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -22,32 +22,32 @@
<ProjectGuid>{4EC107AB-89E8-4A0B-8366-B3E81085AE07}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SubzeroTest</RootNamespace>
- <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@@ -95,6 +95,7 @@
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)third_party\googletest\googletest\include\;$(SolutionDir)third_party\googletest\googletest\;$(SolutionDir)third_party\subzero\src\;$(SolutionDir)third_party\subzero\unittest\;$(SolutionDir)third_party\llvm-subzero\include\;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;SubmoduleCheck;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>gtest/gtest.h</ForcedIncludeFiles>
+ <TreatSpecificWarningsAsErrors>5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -111,6 +112,7 @@
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)third_party\googletest\googletest\include\;$(SolutionDir)third_party\googletest\googletest\;$(SolutionDir)third_party\subzero\src\;$(SolutionDir)third_party\subzero\unittest\;$(SolutionDir)third_party\llvm-subzero\include\;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;SubmoduleCheck;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>gtest/gtest.h</ForcedIncludeFiles>
+ <TreatSpecificWarningsAsErrors>5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -129,6 +131,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)third_party\googletest\googletest\include\;$(SolutionDir)third_party\googletest\googletest\;$(SolutionDir)third_party\subzero\src\;$(SolutionDir)third_party\subzero\unittest\;$(SolutionDir)third_party\llvm-subzero\include\;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;SubmoduleCheck;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>gtest/gtest.h</ForcedIncludeFiles>
+ <TreatSpecificWarningsAsErrors>5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -149,6 +152,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir)third_party\googletest\googletest\include\;$(SolutionDir)third_party\googletest\googletest\;$(SolutionDir)third_party\subzero\src\;$(SolutionDir)third_party\subzero\unittest\;$(SolutionDir)third_party\llvm-subzero\include\;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;SubmoduleCheck;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>gtest/gtest.h</ForcedIncludeFiles>
+ <TreatSpecificWarningsAsErrors>5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
diff --git a/src/Reactor/x86.hpp b/src/Reactor/x86.hpp
index 5e759b3..1b8786e 100644
--- a/src/Reactor/x86.hpp
+++ b/src/Reactor/x86.hpp
@@ -66,7 +66,7 @@
RValue<Short4> packssdw(RValue<Int2> x, RValue<Int2> y);
RValue<Short8> packssdw(RValue<Int4> x, RValue<Int4> y);
RValue<SByte8> packsswb(RValue<Short4> x, RValue<Short4> y);
- RValue<Byte8> packuswb(RValue<UShort4> x, RValue<UShort4> y);
+ RValue<Byte8> packuswb(RValue<Short4> x, RValue<Short4> y);
RValue<UShort8> packusdw(RValue<Int4> x, RValue<Int4> y);
diff --git a/src/Renderer/BUILD.gn b/src/Renderer/BUILD.gn
index a8ad847..04ccd2e 100644
--- a/src/Renderer/BUILD.gn
+++ b/src/Renderer/BUILD.gn
@@ -60,8 +60,5 @@
include_dirs = [
".",
"..",
- "../Common",
- "../Main",
- "../Shader",
]
}
diff --git a/src/Renderer/Blitter.cpp b/src/Renderer/Blitter.cpp
index 0c4a160..3cb0fc9 100644
--- a/src/Renderer/Blitter.cpp
+++ b/src/Renderer/Blitter.cpp
@@ -14,6 +14,7 @@
#include "Blitter.hpp"
+#include "Shader/ShaderCore.hpp"
#include "Reactor/Reactor.hpp"
#include "Common/Memory.hpp"
#include "Common/Debug.hpp"
@@ -22,7 +23,7 @@
{
Blitter::Blitter()
{
- blitCache = new RoutineCache<BlitState>(1024);
+ blitCache = new RoutineCache<State>(1024);
}
Blitter::~Blitter()
@@ -30,7 +31,7 @@
delete blitCache;
}
- void Blitter::clear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
+ void Blitter::clear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
{
if(fastClear(pixel, format, dest, dRect, rgbaMask))
{
@@ -38,14 +39,12 @@
}
sw::Surface *color = sw::Surface::create(1, 1, 1, format, pixel, sw::Surface::bytes(format), sw::Surface::bytes(format));
- Blitter::Options clearOptions = static_cast<sw::Blitter::Options>((rgbaMask & 0xF) | CLEAR_OPERATION);
- SliceRect sRect(dRect);
- sRect.slice = 0;
- blit(color, sRect, dest, dRect, clearOptions);
+ SliceRectF sRect((float)dRect.x0, (float)dRect.y0, (float)dRect.x1, (float)dRect.y1, 0);
+ blit(color, sRect, dest, dRect, {rgbaMask});
delete color;
}
- bool Blitter::fastClear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
+ bool Blitter::fastClear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
{
if(format != FORMAT_A32B32G32R32F)
{
@@ -100,26 +99,33 @@
return false;
}
- uint8_t *d = (uint8_t*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
+ uint8_t *slice = (uint8_t*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
- switch(Surface::bytes(dest->getFormat()))
+ for(int j = 0; j < dest->getSamples(); j++)
{
- case 2:
- for(int i = dRect.y0; i < dRect.y1; i++)
+ uint8_t *d = slice;
+
+ switch(Surface::bytes(dest->getFormat()))
{
- sw::clear((uint16_t*)d, packed, dRect.x1 - dRect.x0);
- d += dest->getInternalPitchB();
+ case 2:
+ for(int i = dRect.y0; i < dRect.y1; i++)
+ {
+ sw::clear((uint16_t*)d, packed, dRect.x1 - dRect.x0);
+ d += dest->getInternalPitchB();
+ }
+ break;
+ case 4:
+ for(int i = dRect.y0; i < dRect.y1; i++)
+ {
+ sw::clear((uint32_t*)d, packed, dRect.x1 - dRect.x0);
+ d += dest->getInternalPitchB();
+ }
+ break;
+ default:
+ assert(false);
}
- break;
- case 4:
- for(int i = dRect.y0; i < dRect.y1; i++)
- {
- sw::clear((uint32_t*)d, packed, dRect.x1 - dRect.x0);
- d += dest->getInternalPitchB();
- }
- break;
- default:
- assert(false);
+
+ slice += dest->getInternalSliceB();
}
dest->unlockInternal();
@@ -127,21 +133,7 @@
return true;
}
- void Blitter::blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil)
- {
- Blitter::Options options = WRITE_RGBA;
- if(filter)
- {
- options = static_cast<Blitter::Options>(options | FILTER_LINEAR);
- }
- if(isStencil)
- {
- options = static_cast<Blitter::Options>(options | USE_STENCIL);
- }
- blit(source, sRect, dest, dRect, options);
- }
-
- void Blitter::blit(Surface *source, const SliceRect &sourceRect, Surface *dest, const SliceRect &destRect, const Blitter::Options& options)
+ void Blitter::blit(Surface *source, const SliceRectF &sourceRect, Surface *dest, const SliceRect &destRect, const Blitter::Options& options)
{
if(dest->getInternalFormat() == FORMAT_NULL)
{
@@ -153,7 +145,7 @@
return;
}
- SliceRect sRect = sourceRect;
+ SliceRectF sRect = sourceRect;
SliceRect dRect = destRect;
bool flipX = destRect.x0 > destRect.x1;
@@ -170,14 +162,14 @@
swap(sRect.y0, sRect.y1);
}
- source->lockInternal(sRect.x0, sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
+ source->lockInternal((int)sRect.x0, (int)sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
- float w = static_cast<float>(sRect.x1 - sRect.x0) / static_cast<float>(dRect.x1 - dRect.x0);
- float h = static_cast<float>(sRect.y1 - sRect.y0) / static_cast<float>(dRect.y1 - dRect.y0);
+ float w = sRect.width() / dRect.width();
+ float h = sRect.height() / dRect.height();
- const float xStart = (float)sRect.x0 + 0.5f * w;
- float y = (float)sRect.y0 + 0.5f * h;
+ const float xStart = sRect.x0 + 0.5f * w;
+ float y = sRect.y0 + 0.5f * h;
for(int j = dRect.y0; j < dRect.y1; j++)
{
@@ -186,7 +178,7 @@
for(int i = dRect.x0; i < dRect.x1; i++)
{
// FIXME: Support RGBA mask
- dest->copyInternal(source, i, j, x, y, (options & FILTER_LINEAR) == FILTER_LINEAR);
+ dest->copyInternal(source, i, j, x, y, options.filter);
x += w;
}
@@ -208,13 +200,13 @@
float d = static_cast<float>(source->getDepth()) / static_cast<float>(dest->getDepth());
float z = 0.5f * d;
- for(int k = 0; k < dest->getDepth(); ++k)
+ for(int k = 0; k < dest->getDepth(); k++)
{
float y = 0.5f * h;
- for(int j = 0; j < dest->getHeight(); ++j)
+ for(int j = 0; j < dest->getHeight(); j++)
{
float x = 0.5f * w;
- for(int i = 0; i < dest->getWidth(); ++i)
+ for(int i = 0; i < dest->getWidth(); i++)
{
dest->copyInternal(source, i, j, k, x, y, z, true);
x += w;
@@ -228,11 +220,11 @@
dest->unlockInternal();
}
- bool Blitter::read(Float4 &c, Pointer<Byte> element, Format format)
+ bool Blitter::read(Float4 &c, Pointer<Byte> element, const State &state)
{
c = Float4(0.0f, 0.0f, 0.0f, 1.0f);
- switch(format)
+ switch(state.sourceFormat)
{
case FORMAT_L8:
c.xyz = Float(Int(*Pointer<Byte>(element)));
@@ -242,7 +234,7 @@
c.w = Float(Int(*Pointer<Byte>(element)));
break;
case FORMAT_R8I:
- case FORMAT_R8I_SNORM:
+ case FORMAT_R8_SNORM:
c.x = Float(Int(*Pointer<SByte>(element)));
c.w = float(0x7F);
break;
@@ -271,7 +263,7 @@
c = Float4(*Pointer<Byte4>(element)).zyxw;
break;
case FORMAT_A8B8G8R8I:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
c = Float4(*Pointer<SByte4>(element));
break;
case FORMAT_A8B8G8R8:
@@ -296,7 +288,7 @@
c.w = float(0xFF);
break;
case FORMAT_X8B8G8R8I:
- case FORMAT_X8B8G8R8I_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
c = Float4(*Pointer<SByte4>(element));
c.w = float(0x7F);
break;
@@ -336,7 +328,7 @@
c.w = float(0xFFFFFFFF);
break;
case FORMAT_G8R8I:
- case FORMAT_G8R8I_SNORM:
+ case FORMAT_G8R8_SNORM:
c.x = Float(Int(*Pointer<SByte>(element + 0)));
c.y = Float(Int(*Pointer<SByte>(element + 1)));
c.w = float(0x7F);
@@ -372,6 +364,7 @@
c = *Pointer<Float4>(element);
break;
case FORMAT_X32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_B32G32R32F:
c.z = *Pointer<Float>(element + 8);
case FORMAT_G32R32F:
@@ -387,6 +380,7 @@
c.z = Float(Int(*Pointer<UShort>(element) & UShort(0x001F)));
break;
case FORMAT_A2B10G10R10:
+ case FORMAT_A2B10G10R10UI:
c.x = Float(Int((*Pointer<UInt>(element) & UInt(0x000003FF))));
c.y = Float(Int((*Pointer<UInt>(element) & UInt(0x000FFC00)) >> 10));
c.z = Float(Int((*Pointer<UInt>(element) & UInt(0x3FF00000)) >> 20));
@@ -401,18 +395,15 @@
case FORMAT_D32:
c.x = Float(Int((*Pointer<UInt>(element))));
break;
- case FORMAT_D32F:
- c.x = *Pointer<Float>(element);
- break;
case FORMAT_D32F_COMPLEMENTARY:
+ case FORMAT_D32FS8_COMPLEMENTARY:
c.x = 1.0f - *Pointer<Float>(element);
break;
+ case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
- c.x = *Pointer<Float>(element);
- break;
case FORMAT_D32FS8_TEXTURE:
- c.x = *Pointer<Float>(element);
- break;
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
c.x = *Pointer<Float>(element);
break;
@@ -426,15 +417,15 @@
return true;
}
- bool Blitter::write(Float4 &c, Pointer<Byte> element, Format format, const Blitter::Options& options)
+ bool Blitter::write(Float4 &c, Pointer<Byte> element, const State &state)
{
- bool writeR = (options & WRITE_RED) == WRITE_RED;
- bool writeG = (options & WRITE_GREEN) == WRITE_GREEN;
- bool writeB = (options & WRITE_BLUE) == WRITE_BLUE;
- bool writeA = (options & WRITE_ALPHA) == WRITE_ALPHA;
+ bool writeR = state.writeRed;
+ bool writeG = state.writeGreen;
+ bool writeB = state.writeBlue;
+ bool writeA = state.writeAlpha;
bool writeRGBA = writeR && writeG && writeB && writeA;
- switch(format)
+ switch(state.destFormat)
{
case FORMAT_L8:
*Pointer<Byte>(element) = Byte(RoundInt(Float(c.x)));
@@ -445,8 +436,8 @@
case FORMAT_A8R8G8B8:
if(writeRGBA)
{
- UShort4 c0 = As<UShort4>(RoundShort4(c.zyxw));
- *Pointer<Byte4>(element) = Byte4(Pack(c0, c0));
+ Short4 c0 = RoundShort4(c.zyxw);
+ *Pointer<Byte4>(element) = Byte4(PackUnsigned(c0, c0));
}
else
{
@@ -460,8 +451,8 @@
case FORMAT_SRGB8_A8:
if(writeRGBA)
{
- UShort4 c0 = As<UShort4>(RoundShort4(c));
- *Pointer<Byte4>(element) = Byte4(Pack(c0, c0));
+ Short4 c0 = RoundShort4(c);
+ *Pointer<Byte4>(element) = Byte4(PackUnsigned(c0, c0));
}
else
{
@@ -474,8 +465,8 @@
case FORMAT_X8R8G8B8:
if(writeRGBA)
{
- UShort4 c0 = As<UShort4>(RoundShort4(c.zyxw)) | UShort4(0x0000, 0x0000, 0x0000, 0xFFFFu);
- *Pointer<Byte4>(element) = Byte4(Pack(c0, c0));
+ Short4 c0 = RoundShort4(c.zyxw) | Short4(0x0000, 0x0000, 0x0000, 0x00FF);
+ *Pointer<Byte4>(element) = Byte4(PackUnsigned(c0, c0));
}
else
{
@@ -489,8 +480,8 @@
case FORMAT_SRGB8_X8:
if(writeRGBA)
{
- UShort4 c0 = As<UShort4>(RoundShort4(c)) | UShort4(0x0000, 0x0000, 0x0000, 0xFFFFu);
- *Pointer<Byte4>(element) = Byte4(Pack(c0, c0));
+ Short4 c0 = RoundShort4(c) | Short4(0x0000, 0x0000, 0x0000, 0x00FF);
+ *Pointer<Byte4>(element) = Byte4(PackUnsigned(c0, c0));
}
else
{
@@ -524,6 +515,7 @@
}
break;
case FORMAT_X32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
if(writeA) { *Pointer<Float>(element + 12) = 1.0f; }
case FORMAT_B32G32R32F:
if(writeR) { *Pointer<Float>(element) = c.x; }
@@ -545,26 +537,26 @@
if(writeR) { *Pointer<Float>(element) = c.x; }
break;
case FORMAT_A8B8G8R8I:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
if(writeA) { *Pointer<SByte>(element + 3) = SByte(RoundInt(Float(c.w))); }
case FORMAT_X8B8G8R8I:
- case FORMAT_X8B8G8R8I_SNORM:
- if(writeA && (format == FORMAT_X8B8G8R8I || format == FORMAT_X8B8G8R8I_SNORM))
+ case FORMAT_X8B8G8R8_SNORM:
+ if(writeA && (state.destFormat == FORMAT_X8B8G8R8I || state.destFormat == FORMAT_X8B8G8R8_SNORM))
{
*Pointer<SByte>(element + 3) = SByte(0x7F);
}
if(writeB) { *Pointer<SByte>(element + 2) = SByte(RoundInt(Float(c.z))); }
case FORMAT_G8R8I:
- case FORMAT_G8R8I_SNORM:
+ case FORMAT_G8R8_SNORM:
if(writeG) { *Pointer<SByte>(element + 1) = SByte(RoundInt(Float(c.y))); }
case FORMAT_R8I:
- case FORMAT_R8I_SNORM:
+ case FORMAT_R8_SNORM:
if(writeR) { *Pointer<SByte>(element) = SByte(RoundInt(Float(c.x))); }
break;
case FORMAT_A8B8G8R8UI:
if(writeA) { *Pointer<Byte>(element + 3) = Byte(RoundInt(Float(c.w))); }
case FORMAT_X8B8G8R8UI:
- if(writeA && (format == FORMAT_X8B8G8R8UI))
+ if(writeA && (state.destFormat == FORMAT_X8B8G8R8UI))
{
*Pointer<Byte>(element + 3) = Byte(0xFF);
}
@@ -738,6 +730,7 @@
}
break;
case FORMAT_A2B10G10R10:
+ case FORMAT_A2B10G10R10UI:
if(writeRGBA)
{
*Pointer<UInt>(element) = UInt(RoundInt(Float(c.x)) |
@@ -768,18 +761,15 @@
case FORMAT_D32:
*Pointer<UInt>(element) = UInt(RoundInt(Float(c.x)));
break;
- case FORMAT_D32F:
- *Pointer<Float>(element) = c.x;
- break;
case FORMAT_D32F_COMPLEMENTARY:
+ case FORMAT_D32FS8_COMPLEMENTARY:
*Pointer<Float>(element) = 1.0f - c.x;
break;
+ case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
- *Pointer<Float>(element) = c.x;
- break;
case FORMAT_D32FS8_TEXTURE:
- *Pointer<Float>(element) = c.x;
- break;
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
*Pointer<Float>(element) = c.x;
break;
@@ -792,11 +782,11 @@
return true;
}
- bool Blitter::read(Int4 &c, Pointer<Byte> element, Format format)
+ bool Blitter::read(Int4 &c, Pointer<Byte> element, const State &state)
{
c = Int4(0, 0, 0, 1);
- switch(format)
+ switch(state.sourceFormat)
{
case FORMAT_A8B8G8R8I:
c = Insert(c, Int(*Pointer<SByte>(element + 3)), 3);
@@ -855,20 +845,20 @@
return true;
}
- bool Blitter::write(Int4 &c, Pointer<Byte> element, Format format, const Blitter::Options& options)
+ bool Blitter::write(Int4 &c, Pointer<Byte> element, const State &state)
{
- bool writeR = (options & WRITE_RED) == WRITE_RED;
- bool writeG = (options & WRITE_GREEN) == WRITE_GREEN;
- bool writeB = (options & WRITE_BLUE) == WRITE_BLUE;
- bool writeA = (options & WRITE_ALPHA) == WRITE_ALPHA;
+ bool writeR = state.writeRed;
+ bool writeG = state.writeGreen;
+ bool writeB = state.writeBlue;
+ bool writeA = state.writeAlpha;
bool writeRGBA = writeR && writeG && writeB && writeA;
- switch(format)
+ switch(state.destFormat)
{
case FORMAT_A8B8G8R8I:
if(writeA) { *Pointer<SByte>(element + 3) = SByte(Extract(c, 3)); }
case FORMAT_X8B8G8R8I:
- if(writeA && (format != FORMAT_A8B8G8R8I))
+ if(writeA && (state.destFormat != FORMAT_A8B8G8R8I))
{
*Pointer<SByte>(element + 3) = SByte(0x7F);
}
@@ -881,7 +871,7 @@
case FORMAT_A8B8G8R8UI:
if(writeA) { *Pointer<Byte>(element + 3) = Byte(Extract(c, 3)); }
case FORMAT_X8B8G8R8UI:
- if(writeA && (format != FORMAT_A8B8G8R8UI))
+ if(writeA && (state.destFormat != FORMAT_A8B8G8R8UI))
{
*Pointer<Byte>(element + 3) = Byte(0xFF);
}
@@ -894,7 +884,7 @@
case FORMAT_A16B16G16R16I:
if(writeA) { *Pointer<Short>(element + 6) = Short(Extract(c, 3)); }
case FORMAT_X16B16G16R16I:
- if(writeA && (format != FORMAT_A16B16G16R16I))
+ if(writeA && (state.destFormat != FORMAT_A16B16G16R16I))
{
*Pointer<Short>(element + 6) = Short(0x7FFF);
}
@@ -907,7 +897,7 @@
case FORMAT_A16B16G16R16UI:
if(writeA) { *Pointer<UShort>(element + 6) = UShort(Extract(c, 3)); }
case FORMAT_X16B16G16R16UI:
- if(writeA && (format != FORMAT_A16B16G16R16UI))
+ if(writeA && (state.destFormat != FORMAT_A16B16G16R16UI))
{
*Pointer<UShort>(element + 6) = UShort(0xFFFF);
}
@@ -990,7 +980,7 @@
return true;
}
- bool Blitter::GetScale(float4& scale, Format format)
+ bool Blitter::GetScale(float4 &scale, Format format)
{
switch(format)
{
@@ -1008,10 +998,10 @@
case FORMAT_SRGB8_A8:
scale = vector(0xFF, 0xFF, 0xFF, 0xFF);
break;
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
scale = vector(0x7F, 0x7F, 0x7F, 0x7F);
break;
case FORMAT_A16B16G16R16:
@@ -1044,9 +1034,11 @@
case FORMAT_A32B32G32R32UI:
case FORMAT_A32B32G32R32F:
case FORMAT_X32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_B32G32R32F:
case FORMAT_G32R32F:
case FORMAT_R32F:
+ case FORMAT_A2B10G10R10UI:
scale = vector(1.0f, 1.0f, 1.0f, 1.0f);
break;
case FORMAT_R5G6B5:
@@ -1065,9 +1057,12 @@
scale = vector(static_cast<float>(0xFFFFFFFF), 0.0f, 0.0f, 0.0f);
break;
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_COMPLEMENTARY:
+ case FORMAT_D32FS8_COMPLEMENTARY:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_S8:
scale = vector(1.0f, 1.0f, 1.0f, 1.0f);
@@ -1079,12 +1074,12 @@
return true;
}
- bool Blitter::ApplyScaleAndClamp(Float4& value, const BlitState& state)
+ bool Blitter::ApplyScaleAndClamp(Float4 &value, const State &state, bool preScaled)
{
float4 scale, unscale;
- if(Surface::isNonNormalizedInteger(state.sourceFormat) &&
- !Surface::isNonNormalizedInteger(state.destFormat) &&
- (state.options & CLEAR_OPERATION))
+ if(state.clearOperation &&
+ Surface::isNonNormalizedInteger(state.sourceFormat) &&
+ !Surface::isNonNormalizedInteger(state.destFormat))
{
// If we're clearing a buffer from an int or uint color into a normalized color,
// then the whole range of the int or uint color must be scaled between 0 and 1.
@@ -1110,12 +1105,26 @@
return false;
}
- if(unscale != scale)
+ bool srcSRGB = Surface::isSRGBformat(state.sourceFormat);
+ bool dstSRGB = Surface::isSRGBformat(state.destFormat);
+
+ if(state.convertSRGB && ((srcSRGB && !preScaled) || dstSRGB)) // One of the formats is sRGB encoded.
+ {
+ value *= preScaled ? Float4(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z, 1.0f / scale.w) : // Unapply scale
+ Float4(1.0f / unscale.x, 1.0f / unscale.y, 1.0f / unscale.z, 1.0f / unscale.w); // Apply unscale
+ value = (srcSRGB && !preScaled) ? sRGBtoLinear(value) : LinearToSRGB(value);
+ value *= Float4(scale.x, scale.y, scale.z, scale.w); // Apply scale
+ }
+ else if(unscale != scale)
{
value *= Float4(scale.x / unscale.x, scale.y / unscale.y, scale.z / unscale.z, scale.w / unscale.w);
}
- if(Surface::isFloatFormat(state.sourceFormat) && !Surface::isFloatFormat(state.destFormat))
+ if(state.destFormat == FORMAT_X32B32G32R32F_UNSIGNED)
+ {
+ value = Max(value, Float4(0.0f)); // TODO: Only necessary if source is signed.
+ }
+ else if(Surface::isFloatFormat(state.sourceFormat) && !Surface::isFloatFormat(state.destFormat))
{
value = Min(value, Float4(scale.x, scale.y, scale.z, scale.w));
@@ -1128,13 +1137,45 @@
return true;
}
- Int Blitter::ComputeOffset(Int& x, Int& y, Int& pitchB, int bytes, bool quadLayout)
+ Int Blitter::ComputeOffset(Int &x, Int &y, Int &pitchB, int bytes, bool quadLayout)
{
- return (quadLayout ? (y & Int(~1)) : RValue<Int>(y)) * pitchB +
- (quadLayout ? ((y & Int(1)) << 1) + (x * 2) - (x & Int(1)) : RValue<Int>(x)) * bytes;
+ if(!quadLayout)
+ {
+ return y * pitchB + x * bytes;
+ }
+ else
+ {
+ // (x & ~1) * 2 + (x & 1) == (x - (x & 1)) * 2 + (x & 1) == x * 2 - (x & 1) * 2 + (x & 1) == x * 2 - (x & 1)
+ return (y & Int(~1)) * pitchB +
+ ((y & Int(1)) * 2 + x * 2 - (x & Int(1))) * bytes;
+ }
}
- Routine *Blitter::generate(BlitState &state)
+ Float4 Blitter::LinearToSRGB(Float4 &c)
+ {
+ Float4 lc = Min(c, Float4(0.0031308f)) * Float4(12.92f);
+ Float4 ec = Float4(1.055f) * power(c, Float4(1.0f / 2.4f)) - Float4(0.055f);
+
+ Float4 s = c;
+ s.xyz = Max(lc, ec);
+
+ return s;
+ }
+
+ Float4 Blitter::sRGBtoLinear(Float4 &c)
+ {
+ Float4 lc = c * Float4(1.0f / 12.92f);
+ Float4 ec = power((c + Float4(0.055f)) * Float4(1.0f / 1.055f), Float4(2.4f));
+
+ Int4 linear = CmpLT(c, Float4(0.04045f));
+
+ Float4 s = c;
+ s.xyz = As<Float4>((linear & As<Int4>(lc)) | (~linear & As<Int4>(ec))); // FIXME: IfThenElse()
+
+ return s;
+ }
+
+ Routine *Blitter::generate(const State &state)
{
Function<Void(Pointer<Byte>)> function;
{
@@ -1170,11 +1211,11 @@
Int4 constantColorI;
bool hasConstantColorF = false;
Float4 constantColorF;
- if(state.options & CLEAR_OPERATION)
+ if(state.clearOperation)
{
if(intBoth) // Integer types
{
- if(!read(constantColorI, source, state.sourceFormat))
+ if(!read(constantColorI, source, state))
{
return nullptr;
}
@@ -1182,7 +1223,7 @@
}
else
{
- if(!read(constantColorF, source, state.sourceFormat))
+ if(!read(constantColorF, source, state))
{
return nullptr;
}
@@ -1205,16 +1246,17 @@
For(Int i = x0d, i < x1d, i++)
{
Pointer<Byte> d = destLine + (dstQuadLayout ? (((j & Int(1)) << 1) + (i * 2) - (i & Int(1))) : RValue<Int>(i)) * dstBytes;
+
if(hasConstantColorI)
{
- if(!write(constantColorI, d, state.destFormat, state.options))
+ if(!write(constantColorI, d, state))
{
return nullptr;
}
}
else if(hasConstantColorF)
{
- if(!write(constantColorF, d, state.destFormat, state.options))
+ if(!write(constantColorF, d, state))
{
return nullptr;
}
@@ -1225,14 +1267,20 @@
Int X = Int(x);
Int Y = Int(y);
+ if(state.clampToEdge)
+ {
+ X = Clamp(X, 0, sWidth - 1);
+ Y = Clamp(Y, 0, sHeight - 1);
+ }
+
Pointer<Byte> s = source + ComputeOffset(X, Y, sPitchB, srcBytes, srcQuadLayout);
- if(!read(color, s, state.sourceFormat))
+ if(!read(color, s, state))
{
return nullptr;
}
- if(!write(color, d, state.destFormat, state.options))
+ if(!write(color, d, state))
{
return nullptr;
}
@@ -1241,70 +1289,107 @@
{
Float4 color;
- if(!(state.options & FILTER_LINEAR) || intSrc)
+ bool preScaled = false;
+ if(!state.filter || intSrc)
{
Int X = Int(x);
Int Y = Int(y);
+ if(state.clampToEdge)
+ {
+ X = Clamp(X, 0, sWidth - 1);
+ Y = Clamp(Y, 0, sHeight - 1);
+ }
+
Pointer<Byte> s = source + ComputeOffset(X, Y, sPitchB, srcBytes, srcQuadLayout);
- if(!read(color, s, state.sourceFormat))
+ if(!read(color, s, state))
{
return nullptr;
}
}
else // Bilinear filtering
{
- Float x0 = x - 0.5f;
- Float y0 = y - 0.5f;
+ Float X = x;
+ Float Y = y;
+
+ if(state.clampToEdge)
+ {
+ X = Min(Max(x, 0.5f), Float(sWidth) - 0.5f);
+ Y = Min(Max(y, 0.5f), Float(sHeight) - 0.5f);
+ }
+
+ Float x0 = X - 0.5f;
+ Float y0 = Y - 0.5f;
Int X0 = Max(Int(x0), 0);
Int Y0 = Max(Int(y0), 0);
- Int X1 = IfThenElse(X0 + 1 >= sWidth, X0, X0 + 1);
- Int Y1 = IfThenElse(Y0 + 1 >= sHeight, Y0, Y0 + 1);
+ Int X1 = X0 + 1;
+ Int Y1 = Y0 + 1;
+ X1 = IfThenElse(X1 >= sWidth, X0, X1);
+ Y1 = IfThenElse(Y1 >= sHeight, Y0, Y1);
Pointer<Byte> s00 = source + ComputeOffset(X0, Y0, sPitchB, srcBytes, srcQuadLayout);
Pointer<Byte> s01 = source + ComputeOffset(X1, Y0, sPitchB, srcBytes, srcQuadLayout);
Pointer<Byte> s10 = source + ComputeOffset(X0, Y1, sPitchB, srcBytes, srcQuadLayout);
Pointer<Byte> s11 = source + ComputeOffset(X1, Y1, sPitchB, srcBytes, srcQuadLayout);
- Float4 c00; if(!read(c00, s00, state.sourceFormat)) return nullptr;
- Float4 c01; if(!read(c01, s01, state.sourceFormat)) return nullptr;
- Float4 c10; if(!read(c10, s10, state.sourceFormat)) return nullptr;
- Float4 c11; if(!read(c11, s11, state.sourceFormat)) return nullptr;
+ Float4 c00; if(!read(c00, s00, state)) return nullptr;
+ Float4 c01; if(!read(c01, s01, state)) return nullptr;
+ Float4 c10; if(!read(c10, s10, state)) return nullptr;
+ Float4 c11; if(!read(c11, s11, state)) return nullptr;
+
+ if(state.convertSRGB && Surface::isSRGBformat(state.sourceFormat)) // sRGB -> RGB
+ {
+ if(!ApplyScaleAndClamp(c00, state)) return nullptr;
+ if(!ApplyScaleAndClamp(c01, state)) return nullptr;
+ if(!ApplyScaleAndClamp(c10, state)) return nullptr;
+ if(!ApplyScaleAndClamp(c11, state)) return nullptr;
+ preScaled = true;
+ }
Float4 fx = Float4(x0 - Float(X0));
Float4 fy = Float4(y0 - Float(Y0));
+ Float4 ix = Float4(1.0f) - fx;
+ Float4 iy = Float4(1.0f) - fy;
- color = c00 * (Float4(1.0f) - fx) * (Float4(1.0f) - fy) +
- c01 * fx * (Float4(1.0f) - fy) +
- c10 * (Float4(1.0f) - fx) * fy +
- c11 * fx * fy;
+ color = (c00 * ix + c01 * fx) * iy +
+ (c10 * ix + c11 * fx) * fy;
}
- if(!ApplyScaleAndClamp(color, state) || !write(color, d, state.destFormat, state.options))
+ if(!ApplyScaleAndClamp(color, state, preScaled))
{
return nullptr;
}
+
+ for(int s = 0; s < state.destSamples; s++)
+ {
+ if(!write(color, d, state))
+ {
+ return nullptr;
+ }
+
+ d += *Pointer<Int>(blit + OFFSET(BlitData,dSliceB));
+ }
}
- if(!hasConstantColorI && !hasConstantColorF) { x += w; }
+ if(!state.clearOperation) { x += w; }
}
- if(!hasConstantColorI && !hasConstantColorF) { y += h; }
+ if(!state.clearOperation) { y += h; }
}
}
return function(L"BlitRoutine");
}
- bool Blitter::blitReactor(Surface *source, const SliceRect &sourceRect, Surface *dest, const SliceRect &destRect, const Blitter::Options& options)
+ bool Blitter::blitReactor(Surface *source, const SliceRectF &sourceRect, Surface *dest, const SliceRect &destRect, const Blitter::Options &options)
{
- ASSERT(!(options & CLEAR_OPERATION) || ((source->getWidth() == 1) && (source->getHeight() == 1) && (source->getDepth() == 1)));
+ ASSERT(!options.clearOperation || ((source->getWidth() == 1) && (source->getHeight() == 1) && (source->getDepth() == 1)));
Rect dRect = destRect;
- Rect sRect = sourceRect;
+ RectF sRect = sourceRect;
if(destRect.x0 > destRect.x1)
{
swap(dRect.x0, dRect.x1);
@@ -1316,15 +1401,19 @@
swap(sRect.y0, sRect.y1);
}
- BlitState state;
+ State state(options);
+ state.clampToEdge = (sourceRect.x0 < 0.0f) ||
+ (sourceRect.y0 < 0.0f) ||
+ (sourceRect.x1 > (float)source->getWidth()) ||
+ (sourceRect.y1 > (float)source->getHeight());
bool useSourceInternal = !source->isExternalDirty();
bool useDestInternal = !dest->isExternalDirty();
- bool isStencil = ((options & USE_STENCIL) == USE_STENCIL);
+ bool isStencil = options.useStencil;
state.sourceFormat = isStencil ? source->getStencilFormat() : source->getFormat(useSourceInternal);
state.destFormat = isStencil ? dest->getStencilFormat() : dest->getFormat(useDestInternal);
- state.options = options;
+ state.destSamples = dest->getSamples();
criticalSection.lock();
Routine *blitRoutine = blitCache->query(state);
@@ -1348,7 +1437,7 @@
BlitData data;
- bool isRGBA = ((options & WRITE_RGBA) == WRITE_RGBA);
+ bool isRGBA = options.writeMask == 0xF;
bool isEntireDest = dest->isEntire(destRect);
data.source = isStencil ? source->lockStencil(0, 0, 0, sw::PUBLIC) :
@@ -1357,11 +1446,12 @@
dest->lock(0, 0, destRect.slice, isRGBA ? (isEntireDest ? sw::LOCK_DISCARD : sw::LOCK_WRITEONLY) : sw::LOCK_READWRITE, sw::PUBLIC, useDestInternal);
data.sPitchB = isStencil ? source->getStencilPitchB() : source->getPitchB(useSourceInternal);
data.dPitchB = isStencil ? dest->getStencilPitchB() : dest->getPitchB(useDestInternal);
+ data.dSliceB = isStencil ? dest->getStencilSliceB() : dest->getSliceB(useDestInternal);
- data.w = 1.0f / (dRect.x1 - dRect.x0) * (sRect.x1 - sRect.x0);
- data.h = 1.0f / (dRect.y1 - dRect.y0) * (sRect.y1 - sRect.y0);
- data.x0 = (float)sRect.x0 + 0.5f * data.w;
- data.y0 = (float)sRect.y0 + 0.5f * data.h;
+ data.w = sRect.width() / dRect.width();
+ data.h = sRect.height() / dRect.height();
+ data.x0 = sRect.x0 + 0.5f * data.w;
+ data.y0 = sRect.y0 + 0.5f * data.h;
data.x0d = dRect.x0;
data.x1d = dRect.x1;
diff --git a/src/Renderer/Blitter.hpp b/src/Renderer/Blitter.hpp
index f04dc24..e3db745 100644
--- a/src/Renderer/Blitter.hpp
+++ b/src/Renderer/Blitter.hpp
@@ -25,29 +25,47 @@
{
class Blitter
{
- enum Options : unsigned char
+ struct Options
{
- FILTER_POINT = 0x00,
- WRITE_RED = 0x01,
- WRITE_GREEN = 0x02,
- WRITE_BLUE = 0x04,
- WRITE_ALPHA = 0x08,
- WRITE_RGBA = WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA,
- FILTER_LINEAR = 0x10,
- CLEAR_OPERATION = 0x20,
- USE_STENCIL = 0x40,
+ Options() = default;
+ Options(bool filter, bool useStencil, bool convertSRGB)
+ : writeMask(0xF), clearOperation(false), filter(filter), useStencil(useStencil), convertSRGB(convertSRGB), clampToEdge(false) {}
+ Options(unsigned int writeMask)
+ : writeMask(writeMask), clearOperation(true), filter(false), useStencil(false), convertSRGB(true), clampToEdge(false) {}
+
+ union
+ {
+ struct
+ {
+ bool writeRed : 1;
+ bool writeGreen : 1;
+ bool writeBlue : 1;
+ bool writeAlpha : 1;
+ };
+
+ unsigned char writeMask;
+ };
+
+ bool clearOperation : 1;
+ bool filter : 1;
+ bool useStencil : 1;
+ bool convertSRGB : 1;
+ bool clampToEdge : 1;
};
- struct BlitState
+ struct State : Options
{
- bool operator==(const BlitState &state) const
+ State() = default;
+ State(const Options &options) : Options(options) {}
+
+ bool operator==(const State &state) const
{
- return memcmp(this, &state, sizeof(BlitState)) == 0;
+ return memcmp(this, &state, sizeof(State)) == 0;
}
Format sourceFormat;
Format destFormat;
- Blitter::Options options;
+ int destSamples;
};
struct BlitData
@@ -56,6 +74,7 @@
void *dest;
int sPitchB;
int dPitchB;
+ int dSliceB;
float x0;
float y0;
@@ -75,25 +94,26 @@
Blitter();
virtual ~Blitter();
- void clear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
- void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false);
+ void clear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
+ void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, const Options &options);
void blit3D(Surface *source, Surface *dest);
private:
- bool fastClear(void* pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
+ bool fastClear(void *pixel, sw::Format format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
- bool read(Float4 &color, Pointer<Byte> element, Format format);
- bool write(Float4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);
- bool read(Int4 &color, Pointer<Byte> element, Format format);
- bool write(Int4 &color, Pointer<Byte> element, Format format, const Blitter::Options& options);
+ bool read(Float4 &color, Pointer<Byte> element, const State &state);
+ bool write(Float4 &color, Pointer<Byte> element, const State &state);
+ bool read(Int4 &color, Pointer<Byte> element, const State &state);
+ bool write(Int4 &color, Pointer<Byte> element, const State &state);
static bool GetScale(float4& scale, Format format);
- static bool ApplyScaleAndClamp(Float4& value, const BlitState& state);
- static Int ComputeOffset(Int& x, Int& y, Int& pitchB, int bytes, bool quadLayout);
- void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, const Blitter::Options& options);
- bool blitReactor(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, const Blitter::Options& options);
- Routine *generate(BlitState &state);
+ static bool ApplyScaleAndClamp(Float4 &value, const State &state, bool preScaled = false);
+ static Int ComputeOffset(Int &x, Int &y, Int &pitchB, int bytes, bool quadLayout);
+ static Float4 LinearToSRGB(Float4 &color);
+ static Float4 sRGBtoLinear(Float4 &color);
+ bool blitReactor(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, const Options &options);
+ Routine *generate(const State &state);
- RoutineCache<BlitState> *blitCache;
+ RoutineCache<State> *blitCache;
MutexLock criticalSection;
};
}
diff --git a/src/Renderer/Clipper.cpp b/src/Renderer/Clipper.cpp
index cfd859f..a100f05 100644
--- a/src/Renderer/Clipper.cpp
+++ b/src/Renderer/Clipper.cpp
@@ -16,7 +16,7 @@
#include "Polygon.hpp"
#include "Renderer.hpp"
-#include "Debug.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
@@ -60,20 +60,21 @@
if(clipFlagsOr & CLIP_USER)
{
+ int clipFlags = draw.clipFlags;
DrawData &data = *draw.data;
if(polygon.n >= 3) {
- if(draw.clipFlags & CLIP_PLANE0) clipPlane(polygon, data.clipPlane[0]);
+ if(clipFlags & CLIP_PLANE0) clipPlane(polygon, data.clipPlane[0]);
if(polygon.n >= 3) {
- if(draw.clipFlags & CLIP_PLANE1) clipPlane(polygon, data.clipPlane[1]);
+ if(clipFlags & CLIP_PLANE1) clipPlane(polygon, data.clipPlane[1]);
if(polygon.n >= 3) {
- if(draw.clipFlags & CLIP_PLANE2) clipPlane(polygon, data.clipPlane[2]);
+ if(clipFlags & CLIP_PLANE2) clipPlane(polygon, data.clipPlane[2]);
if(polygon.n >= 3) {
- if(draw.clipFlags & CLIP_PLANE3) clipPlane(polygon, data.clipPlane[3]);
+ if(clipFlags & CLIP_PLANE3) clipPlane(polygon, data.clipPlane[3]);
if(polygon.n >= 3) {
- if(draw.clipFlags & CLIP_PLANE4) clipPlane(polygon, data.clipPlane[4]);
+ if(clipFlags & CLIP_PLANE4) clipPlane(polygon, data.clipPlane[4]);
if(polygon.n >= 3) {
- if(draw.clipFlags & CLIP_PLANE5) clipPlane(polygon, data.clipPlane[5]);
+ if(clipFlags & CLIP_PLANE5) clipPlane(polygon, data.clipPlane[5]);
}}}}}}
}
diff --git a/src/Renderer/Context.cpp b/src/Renderer/Context.cpp
index e5ee4dc..f9d72a9 100644
--- a/src/Renderer/Context.cpp
+++ b/src/Renderer/Context.cpp
@@ -14,12 +14,12 @@
#include "Context.hpp"
-#include "PixelShader.hpp"
-#include "VertexShader.hpp"
#include "Primitive.hpp"
#include "Surface.hpp"
-#include "Memory.hpp"
-#include "Debug.hpp"
+#include "Shader/PixelShader.hpp"
+#include "Shader/VertexShader.hpp"
+#include "Common/Memory.hpp"
+#include "Common/Debug.hpp"
#include <string.h>
@@ -276,6 +276,9 @@
cullMode = CULL_CLOCKWISE;
alphaReference = 0.0f;
+ depthBias = 0.0f;
+ slopeDepthBias = 0.0f;
+
for(int i = 0; i < RENDERTARGETS; i++)
{
colorWriteMask[i] = 0x0000000F;
@@ -481,7 +484,7 @@
{
if(!colorUsed()) return false;
- if(pixelShaderVersion() >= 0x0300) return false;
+ if(pixelShaderModel() >= 0x0300) return false;
return fogEnable;
}
@@ -613,7 +616,7 @@
bool Context::isProjectionComponent(unsigned int coordinate, int component)
{
- if(pixelShaderVersion() <= 0x0103 && coordinate < 8 && textureTransformProject[coordinate])
+ if(pixelShaderModel() <= 0x0103 && coordinate < 8 && textureTransformProject[coordinate])
{
if(textureTransformCount[coordinate] == 2)
{
@@ -1379,7 +1382,7 @@
return false;
}
- if(textureTransformProject[coordinate] && pixelShaderVersion() <= 0x0103)
+ if(textureTransformProject[coordinate] && pixelShaderModel() <= 0x0103)
{
if(textureTransformCount[coordinate] == 2)
{
@@ -1432,14 +1435,14 @@
return false;
}
- unsigned short Context::pixelShaderVersion() const
+ unsigned short Context::pixelShaderModel() const
{
- return pixelShader ? pixelShader->getVersion() : 0x0000;
+ return pixelShader ? pixelShader->getShaderModel() : 0x0000;
}
- unsigned short Context::vertexShaderVersion() const
+ unsigned short Context::vertexShaderModel() const
{
- return vertexShader ? vertexShader->getVersion() : 0x0000;
+ return vertexShader ? vertexShader->getShaderModel() : 0x0000;
}
int Context::getMultiSampleCount() const
diff --git a/src/Renderer/Context.hpp b/src/Renderer/Context.hpp
index 640ec4e..9274233 100644
--- a/src/Renderer/Context.hpp
+++ b/src/Renderer/Context.hpp
@@ -399,8 +399,8 @@
bool textureActive(int coordinate);
bool textureActive(int coordinate, int component);
- unsigned short pixelShaderVersion() const;
- unsigned short vertexShaderVersion() const;
+ unsigned short pixelShaderModel() const;
+ unsigned short vertexShaderModel() const;
int getMultiSampleCount() const;
int getSuperSampleCount() const;
@@ -434,6 +434,9 @@
CullMode cullMode;
float alphaReference;
+ float depthBias;
+ float slopeDepthBias;
+
TextureStage textureStage[8];
Sampler sampler[TOTAL_IMAGE_UNITS];
@@ -462,8 +465,11 @@
bool textureTransformProject[8];
Surface *renderTarget[RENDERTARGETS];
+ unsigned int renderTargetLayer[RENDERTARGETS];
Surface *depthBuffer;
+ unsigned int depthBufferLayer;
Surface *stencilBuffer;
+ unsigned int stencilBufferLayer;
// Fog
bool fogEnable;
diff --git a/src/Renderer/ETC_Decoder.cpp b/src/Renderer/ETC_Decoder.cpp
index 8e109f3..dbc6276 100644
--- a/src/Renderer/ETC_Decoder.cpp
+++ b/src/Renderer/ETC_Decoder.cpp
@@ -26,6 +26,13 @@
return (value < -128) ? -128 : ((value > 127) ? 127 : value);
}
+ inline int clampEAC(int value, bool isSigned)
+ {
+ int min = isSigned ? -1023 : 0;
+ int max = isSigned ? 1023 : 2047;
+ return (value < min) ? min : ((value > max) ? max : value);
+ }
+
struct bgra8
{
unsigned char b;
@@ -82,35 +89,53 @@
struct ETC2
{
// Decodes unsigned single or dual channel block to bytes
- static void DecodeBlock(const ETC2** sources, unsigned char *dest, int nbChannels, int x, int y, int w, int h, int pitch, bool isSigned)
+ static void DecodeBlock(const ETC2** sources, unsigned char *dest, int nbChannels, int x, int y, int w, int h, int pitch, bool isSigned, bool isEAC)
{
- if(isSigned)
+ if(isEAC)
{
- signed char* sDst = reinterpret_cast<signed char*>(dest);
for(int j = 0; j < 4 && (y + j) < h; j++)
{
+ int* sDst = reinterpret_cast<int*>(dest);
for(int i = 0; i < 4 && (x + i) < w; i++)
{
for(int c = nbChannels - 1; c >= 0; c--)
{
- sDst[i * nbChannels + c] = clampSByte(sources[c]->getSingleChannel(i, j, isSigned));
+ sDst[i * nbChannels + c] = clampEAC(sources[c]->getSingleChannel(i, j, isSigned, true), isSigned);
}
}
- sDst += pitch;
+ dest += pitch;
}
}
else
{
- for(int j = 0; j < 4 && (y + j) < h; j++)
+ if(isSigned)
{
- for(int i = 0; i < 4 && (x + i) < w; i++)
+ signed char* sDst = reinterpret_cast<signed char*>(dest);
+ for(int j = 0; j < 4 && (y + j) < h; j++)
{
- for(int c = nbChannels - 1; c >= 0; c--)
+ for(int i = 0; i < 4 && (x + i) < w; i++)
{
- dest[i * nbChannels + c] = clampByte(sources[c]->getSingleChannel(i, j, isSigned));
+ for(int c = nbChannels - 1; c >= 0; c--)
+ {
+ sDst[i * nbChannels + c] = clampSByte(sources[c]->getSingleChannel(i, j, isSigned, false));
+ }
}
+ sDst += pitch;
}
- dest += pitch;
+ }
+ else
+ {
+ for(int j = 0; j < 4 && (y + j) < h; j++)
+ {
+ for(int i = 0; i < 4 && (x + i) < w; i++)
+ {
+ for(int c = nbChannels - 1; c >= 0; c--)
+ {
+ dest[i * nbChannels + c] = clampByte(sources[c]->getSingleChannel(i, j, isSigned, false));
+ }
+ }
+ dest += pitch;
+ }
}
}
}
@@ -591,10 +616,14 @@
}
// Single channel utility functions
- inline int getSingleChannel(int x, int y, bool isSigned) const
+ inline int getSingleChannel(int x, int y, bool isSigned, bool isEAC) const
{
int codeword = isSigned ? signed_base_codeword : base_codeword;
- return codeword + getSingleChannelModifier(x, y) * multiplier;
+ return isEAC ?
+ ((multiplier == 0) ?
+ (codeword * 8 + 4 + getSingleChannelModifier(x, y)) :
+ (codeword * 8 + 4 + getSingleChannelModifier(x, y) * multiplier * 8)) :
+ codeword + getSingleChannelModifier(x, y) * multiplier;
}
inline int getSingleChannelIndex(int x, int y) const
@@ -661,7 +690,7 @@
unsigned char *dstRow = dst + (y * dstPitch);
for(int x = 0; x < w; x += 4, sources[0]++)
{
- ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 1, x, y, dstW, dstH, dstPitch, inputType == ETC_R_SIGNED);
+ ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 1, x, y, dstW, dstH, dstPitch, inputType == ETC_R_SIGNED, true);
}
}
break;
@@ -673,7 +702,7 @@
unsigned char *dstRow = dst + (y * dstPitch);
for(int x = 0; x < w; x += 4, sources[0] += 2, sources[1] += 2)
{
- ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 2, x, y, dstW, dstH, dstPitch, inputType == ETC_RG_SIGNED);
+ ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 2, x, y, dstW, dstH, dstPitch, inputType == ETC_RG_SIGNED, true);
}
}
break;
@@ -695,7 +724,7 @@
for(int x = 0; x < w; x += 4)
{
// Decode Alpha
- ETC2::DecodeBlock(&sources[0], &(alphaValues[0][0]), 1, x, y, dstW, dstH, 4, false);
+ ETC2::DecodeBlock(&sources[0], &(alphaValues[0][0]), 1, x, y, dstW, dstH, 4, false, false);
sources[0]++; // RGBA packets are 128 bits, so move on to the next 64 bit packet to decode the RGB color
// Decode RGB
diff --git a/src/Renderer/Matrix.cpp b/src/Renderer/Matrix.cpp
index 1b27bf8..0da07e5 100644
--- a/src/Renderer/Matrix.cpp
+++ b/src/Renderer/Matrix.cpp
@@ -15,7 +15,7 @@
#include "Matrix.hpp"
#include "Point.hpp"
-#include "Math.hpp"
+#include "Common/Math.hpp"
namespace sw
{
diff --git a/src/Renderer/PixelProcessor.cpp b/src/Renderer/PixelProcessor.cpp
index db11aed..7ae45e9 100644
--- a/src/Renderer/PixelProcessor.cpp
+++ b/src/Renderer/PixelProcessor.cpp
@@ -14,13 +14,13 @@
#include "PixelProcessor.hpp"
-#include "PixelPipeline.hpp"
-#include "PixelProgram.hpp"
-#include "PixelShader.hpp"
#include "Surface.hpp"
#include "Primitive.hpp"
-#include "Constants.hpp"
-#include "Debug.hpp"
+#include "Shader/PixelPipeline.hpp"
+#include "Shader/PixelProgram.hpp"
+#include "Shader/PixelShader.hpp"
+#include "Shader/Constants.hpp"
+#include "Common/Debug.hpp"
#include <string.h>
@@ -159,19 +159,22 @@
}
}
- void PixelProcessor::setRenderTarget(int index, Surface *renderTarget)
+ void PixelProcessor::setRenderTarget(int index, Surface *renderTarget, unsigned int layer)
{
context->renderTarget[index] = renderTarget;
+ context->renderTargetLayer[index] = layer;
}
- void PixelProcessor::setDepthBuffer(Surface *depthBuffer)
+ void PixelProcessor::setDepthBuffer(Surface *depthBuffer, unsigned int layer)
{
context->depthBuffer = depthBuffer;
+ context->depthBufferLayer = layer;
}
- void PixelProcessor::setStencilBuffer(Surface *stencilBuffer)
+ void PixelProcessor::setStencilBuffer(Surface *stencilBuffer, unsigned int layer)
{
context->stencilBuffer = stencilBuffer;
+ context->stencilBufferLayer = layer;
}
void PixelProcessor::setTexCoordIndex(unsigned int stage, int texCoordIndex)
@@ -489,6 +492,15 @@
else ASSERT(false);
}
+ void PixelProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
+ {
+ if(sampler < TEXTURE_IMAGE_UNITS)
+ {
+ context->sampler[sampler].setCompareFunc(compFunc);
+ }
+ else ASSERT(false);
+ }
+
void PixelProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
{
if(sampler < TEXTURE_IMAGE_UNITS)
@@ -990,6 +1002,7 @@
state.pixelFogMode = context->pixelFogActive();
state.wBasedFog = context->wBasedFog && context->pixelFogActive() != FOG_NONE;
state.perspective = context->perspectiveActive();
+ state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f);
if(context->alphaBlendActive())
{
@@ -1052,7 +1065,7 @@
const bool sprite = context->pointSpriteActive();
const bool flatShading = (context->shadingMode == SHADING_FLAT) || point;
- if(context->pixelShaderVersion() < 0x0300)
+ if(context->pixelShaderModel() < 0x0300)
{
for(int coordinate = 0; coordinate < 8; coordinate++)
{
@@ -1069,7 +1082,7 @@
}
}
- if(context->textureTransformProject[coordinate] && context->pixelShaderVersion() <= 0x0103)
+ if(context->textureTransformProject[coordinate] && context->pixelShaderModel() <= 0x0103)
{
if(context->textureTransformCount[coordinate] == 2)
{
@@ -1163,7 +1176,7 @@
if(!routine)
{
- const bool integerPipeline = (context->pixelShaderVersion() <= 0x0104);
+ const bool integerPipeline = (context->pixelShaderModel() <= 0x0104);
QuadRasterizer *generator = nullptr;
if(integerPipeline)
diff --git a/src/Renderer/PixelProcessor.hpp b/src/Renderer/PixelProcessor.hpp
index 65f6b92..1954610 100644
--- a/src/Renderer/PixelProcessor.hpp
+++ b/src/Renderer/PixelProcessor.hpp
@@ -34,8 +34,8 @@
int shaderID;
- bool depthOverride : 1;
- bool shaderContainsKill : 1;
+ bool depthOverride : 1; // TODO: Eliminate by querying shader.
+ bool shaderContainsKill : 1; // TODO: Eliminate by querying shader.
DepthCompareMode depthCompareMode : BITS(DEPTH_LAST);
AlphaCompareMode alphaCompareMode : BITS(ALPHA_LAST);
@@ -66,6 +66,7 @@
bool occlusionEnabled : 1;
bool wBasedFog : 1;
bool perspective : 1;
+ bool depthClamp : 1;
bool alphaBlendActive : 1;
BlendFactor sourceBlendFactor : BITS(BLEND_LAST);
@@ -196,9 +197,9 @@
void setUniformBuffer(int index, sw::Resource* buffer, int offset);
void lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[]);
- void setRenderTarget(int index, Surface *renderTarget);
- void setDepthBuffer(Surface *depthBuffer);
- void setStencilBuffer(Surface *stencilBuffer);
+ void setRenderTarget(int index, Surface *renderTarget, unsigned int layer = 0);
+ void setDepthBuffer(Surface *depthBuffer, unsigned int layer = 0);
+ void setStencilBuffer(Surface *stencilBuffer, unsigned int layer = 0);
void setTexCoordIndex(unsigned int stage, int texCoordIndex);
void setStageOperation(unsigned int stage, TextureStage::StageOperation stageOperation);
@@ -236,6 +237,7 @@
void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
+ void setCompareFunc(unsigned int sampler, CompareFunc compare);
void setBaseLevel(unsigned int sampler, int baseLevel);
void setMaxLevel(unsigned int sampler, int maxLevel);
void setMinLod(unsigned int sampler, float minLod);
diff --git a/src/Renderer/Primitive.hpp b/src/Renderer/Primitive.hpp
index 9f19c4b..52daa18 100644
--- a/src/Renderer/Primitive.hpp
+++ b/src/Renderer/Primitive.hpp
@@ -16,7 +16,7 @@
#define sw_Primitive_hpp
#include "Vertex.hpp"
-#include "Config.hpp"
+#include "Main/Config.hpp"
namespace sw
{
diff --git a/src/Renderer/QuadRasterizer.cpp b/src/Renderer/QuadRasterizer.cpp
index f88c39e..6b319b4 100644
--- a/src/Renderer/QuadRasterizer.cpp
+++ b/src/Renderer/QuadRasterizer.cpp
@@ -14,11 +14,11 @@
#include "QuadRasterizer.hpp"
-#include "Math.hpp"
#include "Primitive.hpp"
#include "Renderer.hpp"
-#include "Constants.hpp"
-#include "Debug.hpp"
+#include "Shader/Constants.hpp"
+#include "Common/Math.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
@@ -49,6 +49,7 @@
constants = *Pointer<Pointer<Byte>>(data + OFFSET(DrawData,constants));
occlusion = 0;
+ int clusterCount = Renderer::getClusterCount();
Do
{
@@ -158,7 +159,7 @@
}
}
- if(veryEarlyDepthTest && state.multiSample == 1)
+ if(veryEarlyDepthTest && state.multiSample == 1 && !state.depthOverride)
{
if(!state.stencilActive && state.depthTestActive && (state.depthCompareMode == DEPTH_LESSEQUAL || state.depthCompareMode == DEPTH_LESS)) // FIXME: Both modes ok?
{
@@ -179,7 +180,7 @@
For(Int x = x0, x < x1, x += 2)
{
- Float4 z = interpolate(xxxx, Dz[0], z, primitive + OFFSET(Primitive,z), false, false);
+ Float4 z = interpolate(xxxx, Dz[0], z, primitive + OFFSET(Primitive,z), false, false, state.depthClamp);
Float4 zValue;
@@ -283,13 +284,15 @@
for(unsigned int q = 0; q < state.multiSample; q++)
{
Short4 mask = CmpGT(xxxx, xLeft[q]) & CmpGT(xRight[q], xxxx);
- cMask[q] = SignMask(Pack(mask, mask)) & 0x0000000F;
+ cMask[q] = SignMask(PackSigned(mask, mask)) & 0x0000000F;
}
quad(cBuffer, zBuffer, sBuffer, cMask, x, y);
}
}
+ int clusterCount = Renderer::getClusterCount();
+
for(int index = 0; index < RENDERTARGETS; index++)
{
if(state.colorWriteActive(index))
@@ -313,7 +316,7 @@
Until(y >= yMax)
}
- Float4 QuadRasterizer::interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective)
+ Float4 QuadRasterizer::interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective, bool clamp)
{
Float4 interpolant = D;
@@ -327,6 +330,11 @@
}
}
+ if(clamp)
+ {
+ interpolant = Min(Max(interpolant, Float4(0.0f)), Float4(1.0f));
+ }
+
return interpolant;
}
diff --git a/src/Renderer/QuadRasterizer.hpp b/src/Renderer/QuadRasterizer.hpp
index 5616112..1d7681d 100644
--- a/src/Renderer/QuadRasterizer.hpp
+++ b/src/Renderer/QuadRasterizer.hpp
@@ -16,10 +16,9 @@
#define sw_QuadRasterizer_hpp
#include "Rasterizer.hpp"
-#include "ShaderCore.hpp"
-#include "PixelShader.hpp"
-
-#include "Types.hpp"
+#include "Shader/ShaderCore.hpp"
+#include "Shader/PixelShader.hpp"
+#include "Common/Types.hpp"
namespace sw
{
@@ -49,7 +48,7 @@
bool interpolateZ() const;
bool interpolateW() const;
- Float4 interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective);
+ Float4 interpolate(Float4 &x, Float4 &D, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective, bool clamp);
const PixelProcessor::State &state;
const PixelShader *const shader;
diff --git a/src/Renderer/Rasterizer.hpp b/src/Renderer/Rasterizer.hpp
index 8d0b4fb..3811a25 100644
--- a/src/Renderer/Rasterizer.hpp
+++ b/src/Renderer/Rasterizer.hpp
@@ -16,9 +16,8 @@
#define sw_Rasterizer_hpp
#include "Context.hpp"
-
#include "PixelProcessor.hpp"
-#include "Config.hpp"
+#include "Main/Config.hpp"
namespace sw
{
diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp
index 32e2027..2bb699a 100644
--- a/src/Renderer/Renderer.cpp
+++ b/src/Renderer/Renderer.cpp
@@ -15,21 +15,21 @@
#include "Renderer.hpp"
#include "Clipper.hpp"
-#include "Math.hpp"
-#include "FrameBuffer.hpp"
-#include "Timer.hpp"
#include "Surface.hpp"
-#include "Half.hpp"
#include "Primitive.hpp"
#include "Polygon.hpp"
-#include "SwiftConfig.hpp"
-#include "MutexLock.hpp"
-#include "CPUID.hpp"
-#include "Memory.hpp"
-#include "Resource.hpp"
-#include "Constants.hpp"
-#include "Debug.hpp"
+#include "Main/FrameBuffer.hpp"
+#include "Main/SwiftConfig.hpp"
#include "Reactor/Reactor.hpp"
+#include "Shader/Constants.hpp"
+#include "Common/MutexLock.hpp"
+#include "Common/CPUID.hpp"
+#include "Common/Memory.hpp"
+#include "Common/Resource.hpp"
+#include "Common/Half.hpp"
+#include "Common/Math.hpp"
+#include "Common/Timer.hpp"
+#include "Common/Debug.hpp"
#undef max
@@ -61,10 +61,10 @@
extern bool precacheSetup;
extern bool precachePixel;
- int batchSize = 128;
- int threadCount = 1;
- int unitCount = 1;
- int clusterCount = 1;
+ static const int batchSize = 128;
+ AtomicInt threadCount(1);
+ AtomicInt Renderer::unitCount(1);
+ AtomicInt Renderer::clusterCount(1);
TranscendentalPrecision logPrecision = ACCURATE;
TranscendentalPrecision expPrecision = ACCURATE;
@@ -281,7 +281,7 @@
setupPrimitives = &Renderer::setupPoints;
}
- DrawCall *draw = 0;
+ DrawCall *draw = nullptr;
do
{
@@ -290,7 +290,7 @@
if(drawCall[i]->references == -1)
{
draw = drawCall[i];
- drawList[nextDraw % DRAW_COUNT] = draw;
+ drawList[nextDraw & DRAW_COUNT_BITS] = draw;
break;
}
@@ -309,13 +309,12 @@
{
draw->queries = new std::list<Query*>();
bool includePrimitivesWrittenQueries = vertexState.transformFeedbackQueryEnabled && vertexState.transformFeedbackEnabled;
- for(std::list<Query*>::iterator query = queries.begin(); query != queries.end(); query++)
+ for(auto &query : queries)
{
- Query* q = *query;
- if(includePrimitivesWrittenQueries || (q->type != Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN))
+ if(includePrimitivesWrittenQueries || (query->type != Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN))
{
- atomicIncrement(&(q->reference));
- draw->queries->push_back(q);
+ ++query->reference; // Atomic
+ draw->queries->push_back(query);
}
}
}
@@ -402,7 +401,7 @@
}
}
- if(context->pixelShaderVersion() <= 0x0104)
+ if(context->pixelShaderModel() <= 0x0104)
{
for(int stage = 0; stage < 8; stage++)
{
@@ -416,11 +415,11 @@
if(context->vertexShader)
{
- if(context->vertexShader->getVersion() >= 0x0300)
+ if(context->vertexShader->getShaderModel() >= 0x0300)
{
for(int sampler = 0; sampler < VERTEX_TEXTURE_IMAGE_UNITS; sampler++)
{
- if(vertexState.samplerState[sampler].textureType != TEXTURE_NULL)
+ if(vertexState.sampler[sampler].textureType != TEXTURE_NULL)
{
draw->texture[TEXTURE_IMAGE_UNITS + sampler] = context->texture[TEXTURE_IMAGE_UNITS + sampler];
draw->texture[TEXTURE_IMAGE_UNITS + sampler]->lock(PUBLIC, PRIVATE);
@@ -545,7 +544,7 @@
if(context->isDrawTriangle(false))
{
- N += depthBias;
+ N += context->depthBias;
}
if(complementaryDepthBuffer)
@@ -583,7 +582,7 @@
data->halfPixelX = replicate(0.5f / W);
data->halfPixelY = replicate(0.5f / H);
data->viewportHeight = abs(viewport.height);
- data->slopeDepthBias = slopeDepthBias;
+ data->slopeDepthBias = context->slopeDepthBias;
data->depthRange = Z;
data->depthNear = N;
draw->clipFlags = clipFlags;
@@ -607,7 +606,9 @@
if(draw->renderTarget[index])
{
- data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->lockInternal(0, 0, q * ms, LOCK_READWRITE, MANAGED);
+ unsigned int layer = context->renderTargetLayer[index];
+ data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->lockInternal(0, 0, layer, LOCK_READWRITE, MANAGED);
+ data->colorBuffer[index] += q * ms * context->renderTarget[index]->getSliceB(true);
data->colorPitchB[index] = context->renderTarget[index]->getInternalPitchB();
data->colorSliceB[index] = context->renderTarget[index]->getInternalSliceB();
}
@@ -618,14 +619,18 @@
if(draw->depthBuffer)
{
- data->depthBuffer = (float*)context->depthBuffer->lockInternal(0, 0, q * ms, LOCK_READWRITE, MANAGED);
+ unsigned int layer = context->depthBufferLayer;
+ data->depthBuffer = (float*)context->depthBuffer->lockInternal(0, 0, layer, LOCK_READWRITE, MANAGED);
+ data->depthBuffer += q * ms * context->depthBuffer->getSliceB(true);
data->depthPitchB = context->depthBuffer->getInternalPitchB();
data->depthSliceB = context->depthBuffer->getInternalSliceB();
}
if(draw->stencilBuffer)
{
- data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, q * ms, MANAGED);
+ unsigned int layer = context->stencilBufferLayer;
+ data->stencilBuffer = (unsigned char*)context->stencilBuffer->lockStencil(0, 0, layer, MANAGED);
+ data->stencilBuffer += q * ms * context->stencilBuffer->getSliceB(true);
data->stencilPitchB = context->stencilBuffer->getStencilPitchB();
data->stencilSliceB = context->stencilBuffer->getStencilSliceB();
}
@@ -645,7 +650,7 @@
draw->references = (count + batch - 1) / batch;
schedulerMutex.lock();
- nextDraw++;
+ ++nextDraw; // Atomic
schedulerMutex.unlock();
#ifndef NDEBUG
@@ -674,18 +679,12 @@
void Renderer::clear(void *value, Format format, Surface *dest, const Rect &clearRect, unsigned int rgbaMask)
{
- SliceRect rect = clearRect;
- int samples = dest->getDepth();
-
- for(rect.slice = 0; rect.slice < samples; rect.slice++)
- {
- blitter->clear(value, format, dest, rect, rgbaMask);
- }
+ blitter->clear(value, format, dest, clearRect, rgbaMask);
}
- void Renderer::blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil)
+ void Renderer::blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil, bool sRGBconversion)
{
- blitter->blit(source, sRect, dest, dRect, filter, isStencil);
+ blitter->blit(source, sRect, dest, dRect, {filter, isStencil, sRGBconversion});
}
void Renderer::blit3D(Surface *source, Surface *dest)
@@ -750,7 +749,7 @@
pixelProgress[cluster].executing = true;
// Commit to the task queue
- qHead = (qHead + 1) % 32;
+ qHead = (qHead + 1) & TASK_COUNT_BITS;
qSize++;
break;
@@ -769,24 +768,27 @@
for(int unit = 0; unit < unitCount; unit++)
{
- DrawCall *draw = drawList[currentDraw % DRAW_COUNT];
+ DrawCall *draw = drawList[currentDraw & DRAW_COUNT_BITS];
- if(draw->primitive >= draw->count)
+ int primitive = draw->primitive;
+ int count = draw->count;
+
+ if(primitive >= count)
{
- currentDraw++;
+ ++currentDraw; // Atomic
if(currentDraw == nextDraw)
{
return; // No more primitives to process
}
- draw = drawList[currentDraw % DRAW_COUNT];
+ draw = drawList[currentDraw & DRAW_COUNT_BITS];
}
if(!primitiveProgress[unit].references) // Task not already being executed and not still in use by a pixel unit
{
- int primitive = draw->primitive;
- int count = draw->count;
+ primitive = draw->primitive;
+ count = draw->count;
int batch = draw->batchSize;
primitiveProgress[unit].drawCall = currentDraw;
@@ -802,7 +804,7 @@
primitiveProgress[unit].references = -1;
// Commit to the task queue
- qHead = (qHead + 1) % 32;
+ qHead = (qHead + 1) & TASK_COUNT_BITS;
qSize++;
}
}
@@ -812,19 +814,21 @@
{
schedulerMutex.lock();
- if((int)qSize < threadCount - threadsAwake + 1)
+ int curThreadsAwake = threadsAwake;
+
+ if((int)qSize < threadCount - curThreadsAwake + 1)
{
findAvailableTasks();
}
if(qSize != 0)
{
- task[threadIndex] = taskQueue[(qHead - qSize) % 32];
+ task[threadIndex] = taskQueue[(qHead - qSize) & TASK_COUNT_BITS];
qSize--;
- if(threadsAwake != threadCount)
+ if(curThreadsAwake != threadCount)
{
- int wakeup = qSize - threadsAwake + 1;
+ int wakeup = qSize - curThreadsAwake + 1;
for(int i = 0; i < threadCount && wakeup > 0; i++)
{
@@ -834,7 +838,7 @@
task[i].type = Task::RESUME;
resume[i]->signal();
- threadsAwake++;
+ ++threadsAwake; // Atomic
wakeup--;
}
}
@@ -844,7 +848,7 @@
{
task[threadIndex].type = Task::SUSPEND;
- threadsAwake--;
+ --threadsAwake; // Atomic
}
schedulerMutex.unlock();
@@ -864,7 +868,7 @@
int input = primitiveProgress[unit].firstPrimitive;
int count = primitiveProgress[unit].primitiveCount;
- DrawCall *draw = drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
+ DrawCall *draw = drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
int (Renderer::*setupPrimitives)(int batch, int count) = draw->setupPrimitives;
processPrimitiveVertices(unit, input, count, draw->count, threadIndex);
@@ -899,7 +903,7 @@
{
int cluster = task[threadIndex].pixelCluster;
Primitive *primitive = primitiveBatch[unit];
- DrawCall *draw = drawList[pixelProgress[cluster].drawCall % DRAW_COUNT];
+ DrawCall *draw = drawList[pixelProgress[cluster].drawCall & DRAW_COUNT_BITS];
DrawData *data = draw->data;
PixelProcessor::RoutinePointer pixelRoutine = draw->pixelPointer;
@@ -933,7 +937,7 @@
int unit = pixelTask.primitiveUnit;
int cluster = pixelTask.pixelCluster;
- DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
+ DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
DrawData &data = *draw.data;
int primitive = primitiveProgress[unit].firstPrimitive;
int count = primitiveProgress[unit].primitiveCount;
@@ -943,15 +947,15 @@
if(pixelProgress[cluster].processedPrimitives >= draw.count)
{
- pixelProgress[cluster].drawCall++;
+ ++pixelProgress[cluster].drawCall; // Atomic
pixelProgress[cluster].processedPrimitives = 0;
}
- int ref = atomicDecrement(&primitiveProgress[unit].references);
+ int ref = primitiveProgress[unit].references--; // Atomic
if(ref == 0)
{
- ref = atomicDecrement(&draw.references);
+ ref = draw.references--; // Atomic
if(ref == 0)
{
@@ -967,26 +971,24 @@
if(draw.queries)
{
- for(std::list<Query*>::iterator q = draw.queries->begin(); q != draw.queries->end(); q++)
+ for(auto &query : *(draw.queries))
{
- Query *query = *q;
-
switch(query->type)
{
case Query::FRAGMENTS_PASSED:
for(int cluster = 0; cluster < clusterCount; cluster++)
{
- atomicAdd((volatile int*)&query->data, data.occlusion[cluster]);
+ query->data += data.occlusion[cluster];
}
break;
case Query::TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
- atomicAdd((volatile int*)&query->data, processedPrimitives);
+ query->data += processedPrimitives;
break;
default:
break;
}
- atomicDecrement(&query->reference);
+ --query->reference; // Atomic
}
delete draw.queries;
@@ -1069,17 +1071,18 @@
void Renderer::processPrimitiveVertices(int unit, unsigned int start, unsigned int triangleCount, unsigned int loop, int thread)
{
Triangle *triangle = triangleBatch[unit];
- DrawCall *draw = drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
+ int primitiveDrawCall = primitiveProgress[unit].drawCall;
+ DrawCall *draw = drawList[primitiveDrawCall & DRAW_COUNT_BITS];
DrawData *data = draw->data;
VertexTask *task = vertexTask[thread];
const void *indices = data->indices;
VertexProcessor::RoutinePointer vertexRoutine = draw->vertexPointer;
- if(task->vertexCache.drawCall != primitiveProgress[unit].drawCall)
+ if(task->vertexCache.drawCall != primitiveDrawCall)
{
task->vertexCache.clear();
- task->vertexCache.drawCall = primitiveProgress[unit].drawCall;
+ task->vertexCache.drawCall = primitiveDrawCall;
}
unsigned int batch[128][3]; // FIXME: Adjust to dynamic batch size
@@ -1162,9 +1165,18 @@
for(unsigned int i = 0; i < triangleCount; i++)
{
- batch[i][0] = index + 0;
- batch[i][1] = index + (index & 1) + 1;
- batch[i][2] = index + (~index & 1) + 1;
+ if(leadingVertexFirst)
+ {
+ batch[i][0] = index + 0;
+ batch[i][1] = index + (index & 1) + 1;
+ batch[i][2] = index + (~index & 1) + 1;
+ }
+ else
+ {
+ batch[i][0] = index + (index & 1);
+ batch[i][1] = index + (~index & 1);
+ batch[i][2] = index + 2;
+ }
index += 1;
}
@@ -1176,9 +1188,18 @@
for(unsigned int i = 0; i < triangleCount; i++)
{
- batch[i][0] = index + 1;
- batch[i][1] = index + 2;
- batch[i][2] = 0;
+ if(leadingVertexFirst)
+ {
+ batch[i][0] = index + 1;
+ batch[i][1] = index + 2;
+ batch[i][2] = 0;
+ }
+ else
+ {
+ batch[i][0] = 0;
+ batch[i][1] = index + 1;
+ batch[i][2] = index + 2;
+ }
index += 1;
}
@@ -1499,7 +1520,7 @@
Triangle *triangle = triangleBatch[unit];
Primitive *primitive = primitiveBatch[unit];
- DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
+ DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState;
const SetupProcessor::RoutinePointer &setupRoutine = draw.setupPointer;
@@ -1545,7 +1566,7 @@
Primitive *primitive = primitiveBatch[unit];
int visible = 0;
- DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
+ DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState;
const Vertex &v0 = triangle[0].v0;
@@ -1602,7 +1623,7 @@
Primitive *primitive = primitiveBatch[unit];
int visible = 0;
- DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
+ DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState;
const Vertex &v0 = triangle[0].v0;
@@ -1646,7 +1667,7 @@
Primitive *primitive = primitiveBatch[unit];
int visible = 0;
- DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
+ DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState;
int ms = state.multiSample;
@@ -1671,7 +1692,7 @@
Primitive *primitive = primitiveBatch[unit];
int visible = 0;
- DrawCall &draw = *drawList[primitiveProgress[unit].drawCall % DRAW_COUNT];
+ DrawCall &draw = *drawList[primitiveProgress[unit].drawCall & DRAW_COUNT_BITS];
SetupProcessor::State &state = draw.setupState;
int ms = state.multiSample;
@@ -1722,7 +1743,7 @@
return false;
}
- if(false) // Rectangle
+ if(state.multiSample > 1) // Rectangle
{
float4 P[4];
int C[4];
@@ -2382,6 +2403,18 @@
}
}
+ void Renderer::setCompareFunc(SamplerType type, int sampler, CompareFunc compFunc)
+ {
+ if(type == SAMPLER_PIXEL)
+ {
+ PixelProcessor::setCompareFunc(sampler, compFunc);
+ }
+ else
+ {
+ VertexProcessor::setCompareFunc(sampler, compFunc);
+ }
+ }
+
void Renderer::setBaseLevel(SamplerType type, int sampler, int baseLevel)
{
if(type == SAMPLER_PIXEL)
@@ -2447,12 +2480,12 @@
void Renderer::setDepthBias(float bias)
{
- depthBias = bias;
+ context->depthBias = bias;
}
void Renderer::setSlopeDepthBias(float slopeBias)
{
- slopeDepthBias = slopeBias;
+ context->slopeDepthBias = slopeBias;
}
void Renderer::setRasterizerDiscard(bool rasterizerDiscard)
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index e33f828..8893fb58 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -37,11 +37,6 @@
class Renderer;
struct Constants;
- extern int batchSize;
- extern int threadCount;
- extern int unitCount;
- extern int clusterCount;
-
enum TranscendentalPrecision
{
APPROXIMATE,
@@ -110,8 +105,8 @@
}
bool building;
- volatile int reference;
- volatile unsigned int data;
+ AtomicInt reference;
+ AtomicInt data;
const Type type;
};
@@ -213,8 +208,8 @@
~DrawCall();
- DrawType drawType;
- int batchSize;
+ AtomicInt drawType;
+ AtomicInt batchSize;
Routine *vertexRoutine;
Routine *setupRoutine;
@@ -247,11 +242,11 @@
std::list<Query*> *queries;
- int clipFlags;
+ AtomicInt clipFlags;
- volatile int primitive; // Current primitive to enter pipeline
- volatile int count; // Number of primitives to render
- volatile int references; // Remaining references to this draw call, 0 when done drawing, -1 when resources unlocked and slot is free
+ AtomicInt primitive; // Current primitive to enter pipeline
+ AtomicInt count; // Number of primitives to render
+ AtomicInt references; // Remaining references to this draw call, 0 when done drawing, -1 when resources unlocked and slot is free
DrawData *data;
};
@@ -279,9 +274,9 @@
SUSPEND
};
- volatile Type type;
- volatile int primitiveUnit;
- volatile int pixelCluster;
+ AtomicInt type;
+ AtomicInt primitiveUnit;
+ AtomicInt pixelCluster;
};
struct PrimitiveProgress
@@ -295,11 +290,11 @@
references = 0;
}
- volatile int drawCall;
- volatile int firstPrimitive;
- volatile int primitiveCount;
- volatile int visible;
- volatile int references;
+ AtomicInt drawCall;
+ AtomicInt firstPrimitive;
+ AtomicInt primitiveCount;
+ AtomicInt visible;
+ AtomicInt references;
};
struct PixelProgress
@@ -311,9 +306,9 @@
executing = false;
}
- volatile int drawCall;
- volatile int processedPrimitives;
- volatile bool executing;
+ AtomicInt drawCall;
+ AtomicInt processedPrimitives;
+ AtomicInt executing;
};
public:
@@ -327,7 +322,7 @@
void draw(DrawType drawType, unsigned int indexOffset, unsigned int count, bool update = true);
void clear(void *value, Format format, Surface *dest, const Rect &rect, unsigned int rgbaMask);
- void blit(Surface *source, const SliceRect &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false);
+ void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, bool filter, bool isStencil = false, bool sRGBconversion = true);
void blit3D(Surface *source, Surface *dest);
void setIndexBuffer(Resource *indexBuffer);
@@ -353,6 +348,7 @@
void setSwizzleG(SamplerType type, int sampler, SwizzleType swizzleG);
void setSwizzleB(SamplerType type, int sampler, SwizzleType swizzleB);
void setSwizzleA(SamplerType type, int sampler, SwizzleType swizzleA);
+ void setCompareFunc(SamplerType type, int sampler, CompareFunc compare);
void setBaseLevel(SamplerType type, int sampler, int baseLevel);
void setMaxLevel(SamplerType type, int sampler, int maxLevel);
void setMinLod(SamplerType type, int sampler, float minLod);
@@ -405,6 +401,8 @@
void resetTimers();
#endif
+ static int getClusterCount() { return clusterCount; }
+
private:
static void threadFunction(void *parameters);
void threadLoop(int threadIndex);
@@ -449,8 +447,8 @@
Plane clipPlane[MAX_CLIP_PLANES]; // Tranformed to clip space
bool updateClipPlanes;
- volatile bool exitThreads;
- volatile int threadsAwake;
+ AtomicInt exitThreads;
+ AtomicInt threadsAwake;
Thread *worker[16];
Event *resume[16]; // Events for resuming threads
Event *suspend[16]; // Events for suspending threads
@@ -460,16 +458,26 @@
PixelProgress pixelProgress[16];
Task task[16]; // Current tasks for threads
- enum {DRAW_COUNT = 16}; // Number of draw calls buffered
+ enum {
+ DRAW_COUNT = 16, // Number of draw calls buffered (must be power of 2)
+ DRAW_COUNT_BITS = DRAW_COUNT - 1,
+ };
DrawCall *drawCall[DRAW_COUNT];
DrawCall *drawList[DRAW_COUNT];
- volatile int currentDraw;
- volatile int nextDraw;
+ AtomicInt currentDraw;
+ AtomicInt nextDraw;
- Task taskQueue[32];
- unsigned int qHead;
- unsigned int qSize;
+ enum {
+ TASK_COUNT = 32, // Size of the task queue (must be power of 2)
+ TASK_COUNT_BITS = TASK_COUNT - 1,
+ };
+ Task taskQueue[TASK_COUNT];
+ AtomicInt qHead;
+ AtomicInt qSize;
+
+ static AtomicInt unitCount;
+ static AtomicInt clusterCount;
MutexLock schedulerMutex;
diff --git a/src/Renderer/Sampler.cpp b/src/Renderer/Sampler.cpp
index 60f5e35..85448b9 100644
--- a/src/Renderer/Sampler.cpp
+++ b/src/Renderer/Sampler.cpp
@@ -16,8 +16,8 @@
#include "Context.hpp"
#include "Surface.hpp"
-#include "PixelRoutine.hpp"
-#include "Debug.hpp"
+#include "Shader/PixelRoutine.hpp"
+#include "Common/Debug.hpp"
#include <memory.h>
#include <string.h>
@@ -61,12 +61,15 @@
sRGB = false;
gather = false;
highPrecisionFiltering = false;
+ border = 0;
swizzleR = SWIZZLE_RED;
swizzleG = SWIZZLE_GREEN;
swizzleB = SWIZZLE_BLUE;
swizzleA = SWIZZLE_ALPHA;
+ compare = COMPARE_BYPASS;
+
texture.LOD = 0.0f;
exp2LOD = 1.0f;
@@ -93,12 +96,13 @@
state.addressingModeV = getAddressingModeV();
state.addressingModeW = getAddressingModeW();
state.mipmapFilter = mipmapFilter();
- state.sRGB = sRGB && Surface::isSRGBreadable(externalTextureFormat);
+ state.sRGB = (sRGB && Surface::isSRGBreadable(externalTextureFormat)) || Surface::isSRGBformat(internalTextureFormat);
state.swizzleR = swizzleR;
state.swizzleG = swizzleG;
state.swizzleB = swizzleB;
state.swizzleA = swizzleA;
state.highPrecisionFiltering = highPrecisionFiltering;
+ state.compare = getCompareFunc();
#if PERF_PROFILE
state.compressedFormat = Surface::isCompressed(externalTextureFormat);
@@ -114,7 +118,8 @@
{
Mipmap &mipmap = texture.mipmap[level];
- mipmap.buffer[face] = surface->lockInternal(0, 0, 0, LOCK_UNLOCKED, PRIVATE);
+ border = surface->getBorder();
+ mipmap.buffer[face] = surface->lockInternal(-border, -border, 0, LOCK_UNLOCKED, PRIVATE);
if(face == 0)
{
@@ -332,6 +337,11 @@
this->swizzleA = swizzleA;
}
+ void Sampler::setCompareFunc(CompareFunc compare)
+ {
+ this->compare = compare;
+ }
+
void Sampler::setBaseLevel(int baseLevel)
{
texture.baseLevel = baseLevel;
@@ -446,9 +456,9 @@
AddressingMode Sampler::getAddressingModeU() const
{
- if(hasCubeTexture())
+ if(textureType == TEXTURE_CUBE)
{
- return ADDRESSING_CLAMP;
+ return border ? ADDRESSING_SEAMLESS : ADDRESSING_CLAMP;
}
return addressingModeU;
@@ -456,9 +466,9 @@
AddressingMode Sampler::getAddressingModeV() const
{
- if(hasCubeTexture())
+ if(textureType == TEXTURE_CUBE)
{
- return ADDRESSING_CLAMP;
+ return border ? ADDRESSING_SEAMLESS : ADDRESSING_CLAMP;
}
return addressingModeV;
@@ -466,16 +476,28 @@
AddressingMode Sampler::getAddressingModeW() const
{
- if(hasCubeTexture())
- {
- return ADDRESSING_CLAMP;
- }
-
- if(textureType == TEXTURE_2D_ARRAY || textureType == TEXTURE_2D)
+ if(textureType == TEXTURE_2D_ARRAY ||
+ textureType == TEXTURE_2D ||
+ textureType == TEXTURE_CUBE)
{
return ADDRESSING_LAYER;
}
return addressingModeW;
}
+
+ CompareFunc Sampler::getCompareFunc() const
+ {
+ if(getTextureFilter() == FILTER_GATHER)
+ {
+ return COMPARE_BYPASS;
+ }
+
+ if(internalTextureFormat == FORMAT_D32FS8_SHADOW)
+ {
+ return COMPARE_LESSEQUAL;
+ }
+
+ return compare;
+ }
}
diff --git a/src/Renderer/Sampler.hpp b/src/Renderer/Sampler.hpp
index 6fae602..c73721d 100644
--- a/src/Renderer/Sampler.hpp
+++ b/src/Renderer/Sampler.hpp
@@ -69,6 +69,7 @@
{
TEXTURE_NULL,
TEXTURE_2D,
+ TEXTURE_RECTANGLE,
TEXTURE_CUBE,
TEXTURE_3D,
TEXTURE_2D_ARRAY,
@@ -103,13 +104,29 @@
ADDRESSING_CLAMP,
ADDRESSING_MIRROR,
ADDRESSING_MIRRORONCE,
- ADDRESSING_BORDER,
+ ADDRESSING_BORDER, // Single color
+ ADDRESSING_SEAMLESS, // Border of pixels
ADDRESSING_LAYER,
ADDRESSING_TEXELFETCH,
ADDRESSING_LAST = ADDRESSING_TEXELFETCH
};
+ enum CompareFunc ENUM_UNDERLYING_TYPE_UNSIGNED_INT
+ {
+ COMPARE_BYPASS,
+ COMPARE_LESSEQUAL,
+ COMPARE_GREATEREQUAL,
+ COMPARE_LESS,
+ COMPARE_GREATER,
+ COMPARE_EQUAL,
+ COMPARE_NOTEQUAL,
+ COMPARE_ALWAYS,
+ COMPARE_NEVER,
+
+ COMPARE_LAST = COMPARE_NEVER
+ };
+
enum SwizzleType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
SWIZZLE_RED,
@@ -142,6 +159,7 @@
SwizzleType swizzleB : BITS(SWIZZLE_LAST);
SwizzleType swizzleA : BITS(SWIZZLE_LAST);
bool highPrecisionFiltering : 1;
+ CompareFunc compare : BITS(COMPARE_LAST);
#if PERF_PROFILE
bool compressedFormat : 1;
@@ -170,6 +188,7 @@
void setSwizzleG(SwizzleType swizzleG);
void setSwizzleB(SwizzleType swizzleB);
void setSwizzleA(SwizzleType swizzleA);
+ void setCompareFunc(CompareFunc compare);
void setBaseLevel(int baseLevel);
void setMaxLevel(int maxLevel);
void setMinLod(float minLod);
@@ -193,6 +212,7 @@
AddressingMode getAddressingModeU() const;
AddressingMode getAddressingModeV() const;
AddressingMode getAddressingModeW() const;
+ CompareFunc getCompareFunc() const;
Format externalTextureFormat;
Format internalTextureFormat;
@@ -206,11 +226,14 @@
bool sRGB;
bool gather;
bool highPrecisionFiltering;
+ int border;
SwizzleType swizzleR;
SwizzleType swizzleG;
SwizzleType swizzleB;
SwizzleType swizzleA;
+ CompareFunc compare;
+
Texture texture;
float exp2LOD;
diff --git a/src/Renderer/SetupProcessor.cpp b/src/Renderer/SetupProcessor.cpp
index 772327f..c5c2a16 100644
--- a/src/Renderer/SetupProcessor.cpp
+++ b/src/Renderer/SetupProcessor.cpp
@@ -14,13 +14,13 @@
#include "SetupProcessor.hpp"
-#include "SetupRoutine.hpp"
#include "Primitive.hpp"
#include "Polygon.hpp"
#include "Context.hpp"
#include "Renderer.hpp"
-#include "Constants.hpp"
-#include "Debug.hpp"
+#include "Shader/SetupRoutine.hpp"
+#include "Shader/Constants.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
@@ -85,7 +85,7 @@
state.pointSprite = context->pointSpriteActive();
state.cullMode = context->cullMode;
state.twoSidedStencil = context->stencilActive() && context->twoSidedStencil;
- state.slopeDepthBias = slopeDepthBias != 0.0f;
+ state.slopeDepthBias = context->slopeDepthBias != 0.0f;
state.vFace = context->pixelShader && context->pixelShader->isVFaceDeclared();
state.positionRegister = Pos;
@@ -183,7 +183,7 @@
}
}
}
- else if(context->pixelShaderVersion() < 0x0300)
+ else if(context->pixelShaderModel() < 0x0300)
{
for(int coordinate = 0; coordinate < 8; coordinate++)
{
diff --git a/src/Renderer/SetupProcessor.hpp b/src/Renderer/SetupProcessor.hpp
index 2750d4c..be0adc7 100644
--- a/src/Renderer/SetupProcessor.hpp
+++ b/src/Renderer/SetupProcessor.hpp
@@ -95,9 +95,6 @@
void setRoutineCacheSize(int cacheSize);
- float depthBias;
- float slopeDepthBias;
-
private:
Context *const context;
diff --git a/src/Renderer/Stream.hpp b/src/Renderer/Stream.hpp
index 88c0840..969d8b2 100644
--- a/src/Renderer/Stream.hpp
+++ b/src/Renderer/Stream.hpp
@@ -39,7 +39,7 @@
STREAMTYPE_2_10_10_10_INT,
STREAMTYPE_2_10_10_10_UINT,
- STREAMTYPE_LAST = STREAMTYPE_HALF
+ STREAMTYPE_LAST = STREAMTYPE_2_10_10_10_UINT
};
struct StreamResource
diff --git a/src/Renderer/Surface.cpp b/src/Renderer/Surface.cpp
index 6bcc657..8bb80ec 100644
--- a/src/Renderer/Surface.cpp
+++ b/src/Renderer/Surface.cpp
@@ -42,326 +42,352 @@
unsigned int *Surface::palette = 0;
unsigned int Surface::paletteID = 0;
- void Rect::clip(int minX, int minY, int maxX, int maxY)
- {
- x0 = clamp(x0, minX, maxX);
- y0 = clamp(y0, minY, maxY);
- x1 = clamp(x1, minX, maxX);
- y1 = clamp(y1, minY, maxY);
- }
-
void Surface::Buffer::write(int x, int y, int z, const Color<float> &color)
{
- void *element = (unsigned char*)buffer + x * bytes + y * pitchB + z * sliceB;
+ byte *element = (byte*)buffer + (x + border) * bytes + (y + border) * pitchB + z * samples * sliceB;
- write(element, color);
+ for(int i = 0; i < samples; i++)
+ {
+ write(element, color);
+ element += sliceB;
+ }
}
void Surface::Buffer::write(int x, int y, const Color<float> &color)
{
- void *element = (unsigned char*)buffer + x * bytes + y * pitchB;
+ byte *element = (byte*)buffer + (x + border) * bytes + (y + border) * pitchB;
- write(element, color);
+ for(int i = 0; i < samples; i++)
+ {
+ write(element, color);
+ element += sliceB;
+ }
}
inline void Surface::Buffer::write(void *element, const Color<float> &color)
{
+ float r = color.r;
+ float g = color.g;
+ float b = color.b;
+ float a = color.a;
+
+ if(isSRGBformat(format))
+ {
+ r = linearToSRGB(r);
+ g = linearToSRGB(g);
+ b = linearToSRGB(b);
+ }
+
switch(format)
{
case FORMAT_A8:
- *(unsigned char*)element = unorm<8>(color.a);
+ *(unsigned char*)element = unorm<8>(a);
break;
- case FORMAT_R8I_SNORM:
- *(char*)element = snorm<8>(color.r);
+ case FORMAT_R8_SNORM:
+ *(char*)element = snorm<8>(r);
break;
case FORMAT_R8:
- *(unsigned char*)element = unorm<8>(color.r);
+ *(unsigned char*)element = unorm<8>(r);
break;
case FORMAT_R8I:
- *(char*)element = scast<8>(color.r);
+ *(char*)element = scast<8>(r);
break;
case FORMAT_R8UI:
- *(unsigned char*)element = ucast<8>(color.r);
+ *(unsigned char*)element = ucast<8>(r);
break;
case FORMAT_R16I:
- *(short*)element = scast<16>(color.r);
+ *(short*)element = scast<16>(r);
break;
case FORMAT_R16UI:
- *(unsigned short*)element = ucast<16>(color.r);
+ *(unsigned short*)element = ucast<16>(r);
break;
case FORMAT_R32I:
- *(int*)element = static_cast<int>(color.r);
+ *(int*)element = static_cast<int>(r);
break;
case FORMAT_R32UI:
- *(unsigned int*)element = static_cast<unsigned int>(color.r);
+ *(unsigned int*)element = static_cast<unsigned int>(r);
break;
case FORMAT_R3G3B2:
- *(unsigned char*)element = (unorm<3>(color.r) << 5) | (unorm<3>(color.g) << 2) | (unorm<2>(color.b) << 0);
+ *(unsigned char*)element = (unorm<3>(r) << 5) | (unorm<3>(g) << 2) | (unorm<2>(b) << 0);
break;
case FORMAT_A8R3G3B2:
- *(unsigned short*)element = (unorm<8>(color.a) << 8) | (unorm<3>(color.r) << 5) | (unorm<3>(color.g) << 2) | (unorm<2>(color.b) << 0);
+ *(unsigned short*)element = (unorm<8>(a) << 8) | (unorm<3>(r) << 5) | (unorm<3>(g) << 2) | (unorm<2>(b) << 0);
break;
case FORMAT_X4R4G4B4:
- *(unsigned short*)element = 0xF000 | (unorm<4>(color.r) << 8) | (unorm<4>(color.g) << 4) | (unorm<4>(color.b) << 0);
+ *(unsigned short*)element = 0xF000 | (unorm<4>(r) << 8) | (unorm<4>(g) << 4) | (unorm<4>(b) << 0);
break;
case FORMAT_A4R4G4B4:
- *(unsigned short*)element = (unorm<4>(color.a) << 12) | (unorm<4>(color.r) << 8) | (unorm<4>(color.g) << 4) | (unorm<4>(color.b) << 0);
+ *(unsigned short*)element = (unorm<4>(a) << 12) | (unorm<4>(r) << 8) | (unorm<4>(g) << 4) | (unorm<4>(b) << 0);
break;
case FORMAT_R4G4B4A4:
- *(unsigned short*)element = (unorm<4>(color.r) << 12) | (unorm<4>(color.g) << 8) | (unorm<4>(color.b) << 4) | (unorm<4>(color.a) << 0);
+ *(unsigned short*)element = (unorm<4>(r) << 12) | (unorm<4>(g) << 8) | (unorm<4>(b) << 4) | (unorm<4>(a) << 0);
break;
case FORMAT_R5G6B5:
- *(unsigned short*)element = (unorm<5>(color.r) << 11) | (unorm<6>(color.g) << 5) | (unorm<5>(color.b) << 0);
+ *(unsigned short*)element = (unorm<5>(r) << 11) | (unorm<6>(g) << 5) | (unorm<5>(b) << 0);
break;
case FORMAT_A1R5G5B5:
- *(unsigned short*)element = (unorm<1>(color.a) << 15) | (unorm<5>(color.r) << 10) | (unorm<5>(color.g) << 5) | (unorm<5>(color.b) << 0);
+ *(unsigned short*)element = (unorm<1>(a) << 15) | (unorm<5>(r) << 10) | (unorm<5>(g) << 5) | (unorm<5>(b) << 0);
break;
case FORMAT_R5G5B5A1:
- *(unsigned short*)element = (unorm<5>(color.r) << 11) | (unorm<5>(color.g) << 6) | (unorm<5>(color.b) << 1) | (unorm<5>(color.a) << 0);
+ *(unsigned short*)element = (unorm<5>(r) << 11) | (unorm<5>(g) << 6) | (unorm<5>(b) << 1) | (unorm<5>(a) << 0);
break;
case FORMAT_X1R5G5B5:
- *(unsigned short*)element = 0x8000 | (unorm<5>(color.r) << 10) | (unorm<5>(color.g) << 5) | (unorm<5>(color.b) << 0);
+ *(unsigned short*)element = 0x8000 | (unorm<5>(r) << 10) | (unorm<5>(g) << 5) | (unorm<5>(b) << 0);
break;
case FORMAT_A8R8G8B8:
- *(unsigned int*)element = (unorm<8>(color.a) << 24) | (unorm<8>(color.r) << 16) | (unorm<8>(color.g) << 8) | (unorm<8>(color.b) << 0);
+ *(unsigned int*)element = (unorm<8>(a) << 24) | (unorm<8>(r) << 16) | (unorm<8>(g) << 8) | (unorm<8>(b) << 0);
break;
case FORMAT_X8R8G8B8:
- *(unsigned int*)element = 0xFF000000 | (unorm<8>(color.r) << 16) | (unorm<8>(color.g) << 8) | (unorm<8>(color.b) << 0);
+ *(unsigned int*)element = 0xFF000000 | (unorm<8>(r) << 16) | (unorm<8>(g) << 8) | (unorm<8>(b) << 0);
break;
- case FORMAT_A8B8G8R8I_SNORM:
- *(unsigned int*)element = (static_cast<unsigned int>(snorm<8>(color.a)) << 24) |
- (static_cast<unsigned int>(snorm<8>(color.b)) << 16) |
- (static_cast<unsigned int>(snorm<8>(color.g)) << 8) |
- (static_cast<unsigned int>(snorm<8>(color.r)) << 0);
+ case FORMAT_A8B8G8R8_SNORM:
+ *(unsigned int*)element = (static_cast<unsigned int>(snorm<8>(a)) << 24) |
+ (static_cast<unsigned int>(snorm<8>(b)) << 16) |
+ (static_cast<unsigned int>(snorm<8>(g)) << 8) |
+ (static_cast<unsigned int>(snorm<8>(r)) << 0);
break;
case FORMAT_A8B8G8R8:
case FORMAT_SRGB8_A8:
- *(unsigned int*)element = (unorm<8>(color.a) << 24) | (unorm<8>(color.b) << 16) | (unorm<8>(color.g) << 8) | (unorm<8>(color.r) << 0);
+ *(unsigned int*)element = (unorm<8>(a) << 24) | (unorm<8>(b) << 16) | (unorm<8>(g) << 8) | (unorm<8>(r) << 0);
break;
case FORMAT_A8B8G8R8I:
- *(unsigned int*)element = (static_cast<unsigned int>(scast<8>(color.a)) << 24) |
- (static_cast<unsigned int>(scast<8>(color.b)) << 16) |
- (static_cast<unsigned int>(scast<8>(color.g)) << 8) |
- (static_cast<unsigned int>(scast<8>(color.r)) << 0);
+ *(unsigned int*)element = (static_cast<unsigned int>(scast<8>(a)) << 24) |
+ (static_cast<unsigned int>(scast<8>(b)) << 16) |
+ (static_cast<unsigned int>(scast<8>(g)) << 8) |
+ (static_cast<unsigned int>(scast<8>(r)) << 0);
break;
case FORMAT_A8B8G8R8UI:
- *(unsigned int*)element = (ucast<8>(color.a) << 24) | (ucast<8>(color.b) << 16) | (ucast<8>(color.g) << 8) | (ucast<8>(color.r) << 0);
+ *(unsigned int*)element = (ucast<8>(a) << 24) | (ucast<8>(b) << 16) | (ucast<8>(g) << 8) | (ucast<8>(r) << 0);
break;
- case FORMAT_X8B8G8R8I_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
*(unsigned int*)element = 0x7F000000 |
- (static_cast<unsigned int>(snorm<8>(color.b)) << 16) |
- (static_cast<unsigned int>(snorm<8>(color.g)) << 8) |
- (static_cast<unsigned int>(snorm<8>(color.r)) << 0);
+ (static_cast<unsigned int>(snorm<8>(b)) << 16) |
+ (static_cast<unsigned int>(snorm<8>(g)) << 8) |
+ (static_cast<unsigned int>(snorm<8>(r)) << 0);
break;
case FORMAT_X8B8G8R8:
case FORMAT_SRGB8_X8:
- *(unsigned int*)element = 0xFF000000 | (unorm<8>(color.b) << 16) | (unorm<8>(color.g) << 8) | (unorm<8>(color.r) << 0);
+ *(unsigned int*)element = 0xFF000000 | (unorm<8>(b) << 16) | (unorm<8>(g) << 8) | (unorm<8>(r) << 0);
break;
case FORMAT_X8B8G8R8I:
*(unsigned int*)element = 0x7F000000 |
- (static_cast<unsigned int>(scast<8>(color.b)) << 16) |
- (static_cast<unsigned int>(scast<8>(color.g)) << 8) |
- (static_cast<unsigned int>(scast<8>(color.r)) << 0);
+ (static_cast<unsigned int>(scast<8>(b)) << 16) |
+ (static_cast<unsigned int>(scast<8>(g)) << 8) |
+ (static_cast<unsigned int>(scast<8>(r)) << 0);
case FORMAT_X8B8G8R8UI:
- *(unsigned int*)element = 0xFF000000 | (ucast<8>(color.b) << 16) | (ucast<8>(color.g) << 8) | (ucast<8>(color.r) << 0);
+ *(unsigned int*)element = 0xFF000000 | (ucast<8>(b) << 16) | (ucast<8>(g) << 8) | (ucast<8>(r) << 0);
break;
case FORMAT_A2R10G10B10:
- *(unsigned int*)element = (unorm<2>(color.a) << 30) | (unorm<10>(color.r) << 20) | (unorm<10>(color.g) << 10) | (unorm<10>(color.b) << 0);
+ *(unsigned int*)element = (unorm<2>(a) << 30) | (unorm<10>(r) << 20) | (unorm<10>(g) << 10) | (unorm<10>(b) << 0);
break;
case FORMAT_A2B10G10R10:
- *(unsigned int*)element = (unorm<2>(color.a) << 30) | (unorm<10>(color.b) << 20) | (unorm<10>(color.g) << 10) | (unorm<10>(color.r) << 0);
+ case FORMAT_A2B10G10R10UI:
+ *(unsigned int*)element = (unorm<2>(a) << 30) | (unorm<10>(b) << 20) | (unorm<10>(g) << 10) | (unorm<10>(r) << 0);
break;
- case FORMAT_G8R8I_SNORM:
- *(unsigned short*)element = (static_cast<unsigned short>(snorm<8>(color.g)) << 8) |
- (static_cast<unsigned short>(snorm<8>(color.r)) << 0);
+ case FORMAT_G8R8_SNORM:
+ *(unsigned short*)element = (static_cast<unsigned short>(snorm<8>(g)) << 8) |
+ (static_cast<unsigned short>(snorm<8>(r)) << 0);
break;
case FORMAT_G8R8:
- *(unsigned short*)element = (unorm<8>(color.g) << 8) | (unorm<8>(color.r) << 0);
+ *(unsigned short*)element = (unorm<8>(g) << 8) | (unorm<8>(r) << 0);
break;
case FORMAT_G8R8I:
- *(unsigned short*)element = (static_cast<unsigned short>(scast<8>(color.g)) << 8) |
- (static_cast<unsigned short>(scast<8>(color.r)) << 0);
+ *(unsigned short*)element = (static_cast<unsigned short>(scast<8>(g)) << 8) |
+ (static_cast<unsigned short>(scast<8>(r)) << 0);
break;
case FORMAT_G8R8UI:
- *(unsigned short*)element = (ucast<8>(color.g) << 8) | (ucast<8>(color.r) << 0);
+ *(unsigned short*)element = (ucast<8>(g) << 8) | (ucast<8>(r) << 0);
break;
case FORMAT_G16R16:
- *(unsigned int*)element = (unorm<16>(color.g) << 16) | (unorm<16>(color.r) << 0);
+ *(unsigned int*)element = (unorm<16>(g) << 16) | (unorm<16>(r) << 0);
break;
case FORMAT_G16R16I:
- *(unsigned int*)element = (static_cast<unsigned int>(scast<16>(color.g)) << 16) |
- (static_cast<unsigned int>(scast<16>(color.r)) << 0);
+ *(unsigned int*)element = (static_cast<unsigned int>(scast<16>(g)) << 16) |
+ (static_cast<unsigned int>(scast<16>(r)) << 0);
break;
case FORMAT_G16R16UI:
- *(unsigned int*)element = (ucast<16>(color.g) << 16) | (ucast<16>(color.r) << 0);
+ *(unsigned int*)element = (ucast<16>(g) << 16) | (ucast<16>(r) << 0);
break;
case FORMAT_G32R32I:
case FORMAT_G32R32UI:
- ((unsigned int*)element)[0] = static_cast<unsigned int>(color.r);
- ((unsigned int*)element)[1] = static_cast<unsigned int>(color.g);
+ ((unsigned int*)element)[0] = static_cast<unsigned int>(r);
+ ((unsigned int*)element)[1] = static_cast<unsigned int>(g);
break;
case FORMAT_A16B16G16R16:
- ((unsigned short*)element)[0] = unorm<16>(color.r);
- ((unsigned short*)element)[1] = unorm<16>(color.g);
- ((unsigned short*)element)[2] = unorm<16>(color.b);
- ((unsigned short*)element)[3] = unorm<16>(color.a);
+ ((unsigned short*)element)[0] = unorm<16>(r);
+ ((unsigned short*)element)[1] = unorm<16>(g);
+ ((unsigned short*)element)[2] = unorm<16>(b);
+ ((unsigned short*)element)[3] = unorm<16>(a);
break;
case FORMAT_A16B16G16R16I:
- ((unsigned short*)element)[0] = static_cast<unsigned short>(scast<16>(color.r));
- ((unsigned short*)element)[1] = static_cast<unsigned short>(scast<16>(color.g));
- ((unsigned short*)element)[2] = static_cast<unsigned short>(scast<16>(color.b));
- ((unsigned short*)element)[3] = static_cast<unsigned short>(scast<16>(color.a));
+ ((unsigned short*)element)[0] = static_cast<unsigned short>(scast<16>(r));
+ ((unsigned short*)element)[1] = static_cast<unsigned short>(scast<16>(g));
+ ((unsigned short*)element)[2] = static_cast<unsigned short>(scast<16>(b));
+ ((unsigned short*)element)[3] = static_cast<unsigned short>(scast<16>(a));
break;
case FORMAT_A16B16G16R16UI:
- ((unsigned short*)element)[0] = static_cast<unsigned short>(ucast<16>(color.r));
- ((unsigned short*)element)[1] = static_cast<unsigned short>(ucast<16>(color.g));
- ((unsigned short*)element)[2] = static_cast<unsigned short>(ucast<16>(color.b));
- ((unsigned short*)element)[3] = static_cast<unsigned short>(ucast<16>(color.a));
+ ((unsigned short*)element)[0] = static_cast<unsigned short>(ucast<16>(r));
+ ((unsigned short*)element)[1] = static_cast<unsigned short>(ucast<16>(g));
+ ((unsigned short*)element)[2] = static_cast<unsigned short>(ucast<16>(b));
+ ((unsigned short*)element)[3] = static_cast<unsigned short>(ucast<16>(a));
break;
case FORMAT_X16B16G16R16I:
- ((unsigned short*)element)[0] = static_cast<unsigned short>(scast<16>(color.r));
- ((unsigned short*)element)[1] = static_cast<unsigned short>(scast<16>(color.g));
- ((unsigned short*)element)[2] = static_cast<unsigned short>(scast<16>(color.b));
+ ((unsigned short*)element)[0] = static_cast<unsigned short>(scast<16>(r));
+ ((unsigned short*)element)[1] = static_cast<unsigned short>(scast<16>(g));
+ ((unsigned short*)element)[2] = static_cast<unsigned short>(scast<16>(b));
break;
case FORMAT_X16B16G16R16UI:
- ((unsigned short*)element)[0] = static_cast<unsigned short>(ucast<16>(color.r));
- ((unsigned short*)element)[1] = static_cast<unsigned short>(ucast<16>(color.g));
- ((unsigned short*)element)[2] = static_cast<unsigned short>(ucast<16>(color.b));
+ ((unsigned short*)element)[0] = static_cast<unsigned short>(ucast<16>(r));
+ ((unsigned short*)element)[1] = static_cast<unsigned short>(ucast<16>(g));
+ ((unsigned short*)element)[2] = static_cast<unsigned short>(ucast<16>(b));
break;
case FORMAT_A32B32G32R32I:
case FORMAT_A32B32G32R32UI:
- ((unsigned int*)element)[0] = static_cast<unsigned int>(color.r);
- ((unsigned int*)element)[1] = static_cast<unsigned int>(color.g);
- ((unsigned int*)element)[2] = static_cast<unsigned int>(color.b);
- ((unsigned int*)element)[3] = static_cast<unsigned int>(color.a);
+ ((unsigned int*)element)[0] = static_cast<unsigned int>(r);
+ ((unsigned int*)element)[1] = static_cast<unsigned int>(g);
+ ((unsigned int*)element)[2] = static_cast<unsigned int>(b);
+ ((unsigned int*)element)[3] = static_cast<unsigned int>(a);
break;
case FORMAT_X32B32G32R32I:
case FORMAT_X32B32G32R32UI:
- ((unsigned int*)element)[0] = static_cast<unsigned int>(color.r);
- ((unsigned int*)element)[1] = static_cast<unsigned int>(color.g);
- ((unsigned int*)element)[2] = static_cast<unsigned int>(color.b);
+ ((unsigned int*)element)[0] = static_cast<unsigned int>(r);
+ ((unsigned int*)element)[1] = static_cast<unsigned int>(g);
+ ((unsigned int*)element)[2] = static_cast<unsigned int>(b);
break;
case FORMAT_V8U8:
- *(unsigned short*)element = (snorm<8>(color.g) << 8) | (snorm<8>(color.r) << 0);
+ *(unsigned short*)element = (snorm<8>(g) << 8) | (snorm<8>(r) << 0);
break;
case FORMAT_L6V5U5:
- *(unsigned short*)element = (unorm<6>(color.b) << 10) | (snorm<5>(color.g) << 5) | (snorm<5>(color.r) << 0);
+ *(unsigned short*)element = (unorm<6>(b) << 10) | (snorm<5>(g) << 5) | (snorm<5>(r) << 0);
break;
case FORMAT_Q8W8V8U8:
- *(unsigned int*)element = (snorm<8>(color.a) << 24) | (snorm<8>(color.b) << 16) | (snorm<8>(color.g) << 8) | (snorm<8>(color.r) << 0);
+ *(unsigned int*)element = (snorm<8>(a) << 24) | (snorm<8>(b) << 16) | (snorm<8>(g) << 8) | (snorm<8>(r) << 0);
break;
case FORMAT_X8L8V8U8:
- *(unsigned int*)element = 0xFF000000 | (unorm<8>(color.b) << 16) | (snorm<8>(color.g) << 8) | (snorm<8>(color.r) << 0);
+ *(unsigned int*)element = 0xFF000000 | (unorm<8>(b) << 16) | (snorm<8>(g) << 8) | (snorm<8>(r) << 0);
break;
case FORMAT_V16U16:
- *(unsigned int*)element = (snorm<16>(color.g) << 16) | (snorm<16>(color.r) << 0);
+ *(unsigned int*)element = (snorm<16>(g) << 16) | (snorm<16>(r) << 0);
break;
case FORMAT_A2W10V10U10:
- *(unsigned int*)element = (unorm<2>(color.a) << 30) | (snorm<10>(color.b) << 20) | (snorm<10>(color.g) << 10) | (snorm<10>(color.r) << 0);
+ *(unsigned int*)element = (unorm<2>(a) << 30) | (snorm<10>(b) << 20) | (snorm<10>(g) << 10) | (snorm<10>(r) << 0);
break;
case FORMAT_A16W16V16U16:
- ((unsigned short*)element)[0] = snorm<16>(color.r);
- ((unsigned short*)element)[1] = snorm<16>(color.g);
- ((unsigned short*)element)[2] = snorm<16>(color.b);
- ((unsigned short*)element)[3] = unorm<16>(color.a);
+ ((unsigned short*)element)[0] = snorm<16>(r);
+ ((unsigned short*)element)[1] = snorm<16>(g);
+ ((unsigned short*)element)[2] = snorm<16>(b);
+ ((unsigned short*)element)[3] = unorm<16>(a);
break;
case FORMAT_Q16W16V16U16:
- ((unsigned short*)element)[0] = snorm<16>(color.r);
- ((unsigned short*)element)[1] = snorm<16>(color.g);
- ((unsigned short*)element)[2] = snorm<16>(color.b);
- ((unsigned short*)element)[3] = snorm<16>(color.a);
+ ((unsigned short*)element)[0] = snorm<16>(r);
+ ((unsigned short*)element)[1] = snorm<16>(g);
+ ((unsigned short*)element)[2] = snorm<16>(b);
+ ((unsigned short*)element)[3] = snorm<16>(a);
break;
case FORMAT_R8G8B8:
- ((unsigned char*)element)[0] = unorm<8>(color.b);
- ((unsigned char*)element)[1] = unorm<8>(color.g);
- ((unsigned char*)element)[2] = unorm<8>(color.r);
+ ((unsigned char*)element)[0] = unorm<8>(b);
+ ((unsigned char*)element)[1] = unorm<8>(g);
+ ((unsigned char*)element)[2] = unorm<8>(r);
break;
case FORMAT_B8G8R8:
- ((unsigned char*)element)[0] = unorm<8>(color.r);
- ((unsigned char*)element)[1] = unorm<8>(color.g);
- ((unsigned char*)element)[2] = unorm<8>(color.b);
+ ((unsigned char*)element)[0] = unorm<8>(r);
+ ((unsigned char*)element)[1] = unorm<8>(g);
+ ((unsigned char*)element)[2] = unorm<8>(b);
break;
case FORMAT_R16F:
- *(half*)element = (half)color.r;
+ *(half*)element = (half)r;
break;
case FORMAT_A16F:
- *(half*)element = (half)color.a;
+ *(half*)element = (half)a;
break;
case FORMAT_G16R16F:
- ((half*)element)[0] = (half)color.r;
- ((half*)element)[1] = (half)color.g;
+ ((half*)element)[0] = (half)r;
+ ((half*)element)[1] = (half)g;
break;
+ case FORMAT_X16B16G16R16F_UNSIGNED:
+ r = max(r, 0.0f); g = max(g, 0.0f); b = max(b, 0.0f);
+ // Fall through to FORMAT_X16B16G16R16F.
+ case FORMAT_X16B16G16R16F:
+ ((half*)element)[3] = 1.0f;
+ // Fall through to FORMAT_B16G16R16F.
case FORMAT_B16G16R16F:
- ((half*)element)[0] = (half)color.r;
- ((half*)element)[1] = (half)color.g;
- ((half*)element)[2] = (half)color.b;
+ ((half*)element)[0] = (half)r;
+ ((half*)element)[1] = (half)g;
+ ((half*)element)[2] = (half)b;
break;
case FORMAT_A16B16G16R16F:
- ((half*)element)[0] = (half)color.r;
- ((half*)element)[1] = (half)color.g;
- ((half*)element)[2] = (half)color.b;
- ((half*)element)[3] = (half)color.a;
+ ((half*)element)[0] = (half)r;
+ ((half*)element)[1] = (half)g;
+ ((half*)element)[2] = (half)b;
+ ((half*)element)[3] = (half)a;
break;
case FORMAT_A32F:
- *(float*)element = color.a;
+ *(float*)element = a;
break;
case FORMAT_R32F:
- *(float*)element = color.r;
+ *(float*)element = r;
break;
case FORMAT_G32R32F:
- ((float*)element)[0] = color.r;
- ((float*)element)[1] = color.g;
+ ((float*)element)[0] = r;
+ ((float*)element)[1] = g;
break;
+ case FORMAT_X32B32G32R32F_UNSIGNED:
+ r = max(r, 0.0f); g = max(g, 0.0f); b = max(b, 0.0f);
+ // Fall through to FORMAT_X32B32G32R32F.
case FORMAT_X32B32G32R32F:
((float*)element)[3] = 1.0f;
+ // Fall through to FORMAT_B32G32R32F.
case FORMAT_B32G32R32F:
- ((float*)element)[0] = color.r;
- ((float*)element)[1] = color.g;
- ((float*)element)[2] = color.b;
+ ((float*)element)[0] = r;
+ ((float*)element)[1] = g;
+ ((float*)element)[2] = b;
break;
case FORMAT_A32B32G32R32F:
- ((float*)element)[0] = color.r;
- ((float*)element)[1] = color.g;
- ((float*)element)[2] = color.b;
- ((float*)element)[3] = color.a;
+ ((float*)element)[0] = r;
+ ((float*)element)[1] = g;
+ ((float*)element)[2] = b;
+ ((float*)element)[3] = a;
break;
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
- *((float*)element) = color.r;
+ *((float*)element) = r;
break;
case FORMAT_D32F_COMPLEMENTARY:
- *((float*)element) = 1 - color.r;
+ case FORMAT_D32FS8_COMPLEMENTARY:
+ *((float*)element) = 1 - r;
break;
case FORMAT_S8:
- *((unsigned char*)element) = unorm<8>(color.r);
+ *((unsigned char*)element) = unorm<8>(r);
break;
case FORMAT_L8:
- *(unsigned char*)element = unorm<8>(color.r);
+ *(unsigned char*)element = unorm<8>(r);
break;
case FORMAT_A4L4:
- *(unsigned char*)element = (unorm<4>(color.a) << 4) | (unorm<4>(color.r) << 0);
+ *(unsigned char*)element = (unorm<4>(a) << 4) | (unorm<4>(r) << 0);
break;
case FORMAT_L16:
- *(unsigned short*)element = unorm<16>(color.r);
+ *(unsigned short*)element = unorm<16>(r);
break;
case FORMAT_A8L8:
- *(unsigned short*)element = (unorm<8>(color.a) << 8) | (unorm<8>(color.r) << 0);
+ *(unsigned short*)element = (unorm<8>(a) << 8) | (unorm<8>(r) << 0);
break;
case FORMAT_L16F:
- *(half*)element = (half)color.r;
+ *(half*)element = (half)r;
break;
case FORMAT_A16L16F:
- ((half*)element)[0] = (half)color.r;
- ((half*)element)[1] = (half)color.a;
+ ((half*)element)[0] = (half)r;
+ ((half*)element)[1] = (half)a;
break;
case FORMAT_L32F:
- *(float*)element = color.r;
+ *(float*)element = r;
break;
case FORMAT_A32L32F:
- ((float*)element)[0] = color.r;
- ((float*)element)[1] = color.a;
+ ((float*)element)[0] = r;
+ ((float*)element)[1] = a;
break;
default:
ASSERT(false);
@@ -370,14 +396,14 @@
Color<float> Surface::Buffer::read(int x, int y, int z) const
{
- void *element = (unsigned char*)buffer + x * bytes + y * pitchB + z * sliceB;
+ void *element = (unsigned char*)buffer + (x + border) * bytes + (y + border) * pitchB + z * samples * sliceB;
return read(element);
}
Color<float> Surface::Buffer::read(int x, int y) const
{
- void *element = (unsigned char*)buffer + x * bytes + y * pitchB;
+ void *element = (unsigned char*)buffer + (x + border) * bytes + (y + border) * pitchB;
return read(element);
}
@@ -421,7 +447,7 @@
b = 0;
a = *(unsigned char*)element * (1.0f / 0xFF);
break;
- case FORMAT_R8I_SNORM:
+ case FORMAT_R8_SNORM:
r = max((*(signed char*)element) * (1.0f / 0x7F), -1.0f);
break;
case FORMAT_R8:
@@ -538,7 +564,7 @@
b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
}
break;
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
{
signed char* abgr = (signed char*)element;
@@ -579,7 +605,7 @@
a = abgr[3];
}
break;
- case FORMAT_X8B8G8R8I_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
{
signed char* bgr = (signed char*)element;
@@ -616,7 +642,7 @@
b = bgr[2];
}
break;
- case FORMAT_G8R8I_SNORM:
+ case FORMAT_G8R8_SNORM:
{
signed char* gr = (signed char*)element;
@@ -698,6 +724,16 @@
r = (abgr & 0x000003FF) * (1.0f / 0x000003FF);
}
break;
+ case FORMAT_A2B10G10R10UI:
+ {
+ unsigned int abgr = *(unsigned int*)element;
+
+ a = static_cast<float>((abgr & 0xC0000000) >> 30);
+ b = static_cast<float>((abgr & 0x3FF00000) >> 20);
+ g = static_cast<float>((abgr & 0x000FFC00) >> 10);
+ r = static_cast<float>(abgr & 0x000003FF);
+ }
+ break;
case FORMAT_A16B16G16R16I:
{
short* abgr = (short*)element;
@@ -936,6 +972,8 @@
r = ((half*)element)[0];
g = ((half*)element)[1];
break;
+ case FORMAT_X16B16G16R16F:
+ case FORMAT_X16B16G16R16F_UNSIGNED:
case FORMAT_B16G16R16F:
r = ((half*)element)[0];
g = ((half*)element)[1];
@@ -958,6 +996,7 @@
g = ((float*)element)[1];
break;
case FORMAT_X32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_B32G32R32F:
r = ((float*)element)[0];
g = ((float*)element)[1];
@@ -970,8 +1009,10 @@
a = ((float*)element)[3];
break;
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
r = *(float*)element;
g = r;
@@ -979,6 +1020,7 @@
a = r;
break;
case FORMAT_D32F_COMPLEMENTARY:
+ case FORMAT_D32FS8_COMPLEMENTARY:
r = 1.0f - *(float*)element;
g = r;
b = r;
@@ -991,12 +1033,12 @@
ASSERT(false);
}
- // if(sRGB)
- // {
- // r = sRGBtoLinear(r);
- // g = sRGBtoLinear(g);
- // b = sRGBtoLinear(b);
- // }
+ if(isSRGBformat(format))
+ {
+ r = sRGBtoLinear(r);
+ g = sRGBtoLinear(g);
+ b = sRGBtoLinear(b);
+ }
return Color<float>(r, g, b, a);
}
@@ -1041,7 +1083,7 @@
return c000 + c100 + c010 + c110 + c001 + c101 + c011 + c111;
}
- Color<float> Surface::Buffer::sample(float x, float y) const
+ Color<float> Surface::Buffer::sample(float x, float y, int layer) const
{
x -= 0.5f;
y -= 0.5f;
@@ -1052,10 +1094,10 @@
int y0 = clamp((int)y, 0, height - 1);
int y1 = (y0 + 1 >= height) ? y0 : y0 + 1;
- Color<float> c00 = read(x0, y0);
- Color<float> c10 = read(x1, y0);
- Color<float> c01 = read(x0, y1);
- Color<float> c11 = read(x1, y1);
+ Color<float> c00 = read(x0, y0, layer);
+ Color<float> c10 = read(x1, y0, layer);
+ Color<float> c01 = read(x0, y1, layer);
+ Color<float> c11 = read(x1, y1, layer);
float fx = x - x0;
float fy = y - y0;
@@ -1076,6 +1118,7 @@
{
case LOCK_UNLOCKED:
case LOCK_READONLY:
+ case LOCK_UPDATE:
break;
case LOCK_WRITEONLY:
case LOCK_READWRITE:
@@ -1088,11 +1131,12 @@
if(buffer)
{
+ x += border;
+ y += border;
+
switch(format)
{
- #if S3TC_SUPPORT
case FORMAT_DXT1:
- #endif
case FORMAT_ATI1:
case FORMAT_ETC1:
case FORMAT_R11_EAC:
@@ -1148,18 +1192,16 @@
case FORMAT_RGBA_ASTC_12x12_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR:
return (unsigned char*)buffer + 16 * (x / 12) + (y / 12) * pitchB + z * sliceB;
- #if S3TC_SUPPORT
case FORMAT_DXT3:
case FORMAT_DXT5:
- #endif
case FORMAT_ATI2:
return (unsigned char*)buffer + 16 * (x / 4) + (y / 4) * pitchB + z * sliceB;
default:
- return (unsigned char*)buffer + x * bytes + y * pitchB + z * sliceB;
+ return (unsigned char*)buffer + x * bytes + y * pitchB + z * samples * sliceB;
}
}
- return 0;
+ return nullptr;
}
void Surface::Buffer::unlockRect()
@@ -1172,8 +1214,8 @@
public:
SurfaceImplementation(int width, int height, int depth, Format format, void *pixels, int pitch, int slice)
: Surface(width, height, depth, format, pixels, pitch, slice) {}
- SurfaceImplementation(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0)
- : Surface(texture, width, height, depth, format, lockable, renderTarget, pitchP) {}
+ SurfaceImplementation(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0)
+ : Surface(texture, width, height, depth, border, samples, format, lockable, renderTarget, pitchP) {}
~SurfaceImplementation() override {};
void *lockInternal(int x, int y, int z, Lock lock, Accessor client) override
@@ -1192,9 +1234,9 @@
return new SurfaceImplementation(width, height, depth, format, pixels, pitch, slice);
}
- Surface *Surface::create(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchPprovided)
+ Surface *Surface::create(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchPprovided)
{
- return new SurfaceImplementation(texture, width, height, depth, format, lockable, renderTarget, pitchPprovided);
+ return new SurfaceImplementation(texture, width, height, depth, border, samples, format, lockable, renderTarget, pitchPprovided);
}
Surface::Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice) : lockable(true), renderTarget(false)
@@ -1208,92 +1250,105 @@
external.width = width;
external.height = height;
external.depth = depth;
+ external.samples = 1;
external.format = format;
external.bytes = bytes(external.format);
external.pitchB = pitch;
external.pitchP = external.bytes ? pitch / external.bytes : 0;
external.sliceB = slice;
external.sliceP = external.bytes ? slice / external.bytes : 0;
+ external.border = 0;
external.lock = LOCK_UNLOCKED;
external.dirty = true;
- internal.buffer = 0;
+ internal.buffer = nullptr;
internal.width = width;
internal.height = height;
internal.depth = depth;
+ internal.samples = 1;
internal.format = selectInternalFormat(format);
internal.bytes = bytes(internal.format);
- internal.pitchB = pitchB(internal.width, internal.format, false);
- internal.pitchP = pitchP(internal.width, internal.format, false);
- internal.sliceB = sliceB(internal.width, internal.height, internal.format, false);
- internal.sliceP = sliceP(internal.width, internal.height, internal.format, false);
+ internal.pitchB = pitchB(internal.width, 0, internal.format, false);
+ internal.pitchP = pitchP(internal.width, 0, internal.format, false);
+ internal.sliceB = sliceB(internal.width, internal.height, 0, internal.format, false);
+ internal.sliceP = sliceP(internal.width, internal.height, 0, internal.format, false);
+ internal.border = 0;
internal.lock = LOCK_UNLOCKED;
internal.dirty = false;
- stencil.buffer = 0;
+ stencil.buffer = nullptr;
stencil.width = width;
stencil.height = height;
stencil.depth = depth;
- stencil.format = FORMAT_S8;
+ stencil.samples = 1;
+ stencil.format = isStencil(format) ? FORMAT_S8 : FORMAT_NULL;
stencil.bytes = bytes(stencil.format);
- stencil.pitchB = pitchB(stencil.width, stencil.format, false);
- stencil.pitchP = pitchP(stencil.width, stencil.format, false);
- stencil.sliceB = sliceB(stencil.width, stencil.height, stencil.format, false);
- stencil.sliceP = sliceP(stencil.width, stencil.height, stencil.format, false);
+ stencil.pitchB = pitchB(stencil.width, 0, stencil.format, false);
+ stencil.pitchP = pitchP(stencil.width, 0, stencil.format, false);
+ stencil.sliceB = sliceB(stencil.width, stencil.height, 0, stencil.format, false);
+ stencil.sliceP = sliceP(stencil.width, stencil.height, 0, stencil.format, false);
+ stencil.border = 0;
stencil.lock = LOCK_UNLOCKED;
stencil.dirty = false;
- dirtyMipmaps = true;
+ dirtyContents = true;
paletteUsed = 0;
}
- Surface::Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchPprovided) : lockable(lockable), renderTarget(renderTarget)
+ Surface::Surface(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchPprovided) : lockable(lockable), renderTarget(renderTarget)
{
resource = texture ? texture : new Resource(0);
- hasParent = texture != 0;
+ hasParent = texture != nullptr;
ownExternal = true;
depth = max(1, depth);
+ samples = max(1, samples);
- external.buffer = 0;
+ external.buffer = nullptr;
external.width = width;
external.height = height;
external.depth = depth;
+ external.samples = (short)samples;
external.format = format;
external.bytes = bytes(external.format);
- external.pitchB = pitchB(external.width, external.format, renderTarget && !texture);
- external.pitchP = pitchP(external.width, external.format, renderTarget && !texture);
- external.sliceB = sliceB(external.width, external.height, external.format, renderTarget && !texture);
- external.sliceP = sliceP(external.width, external.height, external.format, renderTarget && !texture);
+ external.pitchB = pitchB(external.width, 0, external.format, renderTarget && !texture);
+ external.pitchP = pitchP(external.width, 0, external.format, renderTarget && !texture);
+ external.sliceB = sliceB(external.width, external.height, 0, external.format, renderTarget && !texture);
+ external.sliceP = sliceP(external.width, external.height, 0, external.format, renderTarget && !texture);
+ external.border = 0;
external.lock = LOCK_UNLOCKED;
external.dirty = false;
- internal.buffer = 0;
+ internal.buffer = nullptr;
internal.width = width;
internal.height = height;
internal.depth = depth;
+ internal.samples = (short)samples;
internal.format = selectInternalFormat(format);
internal.bytes = bytes(internal.format);
- internal.pitchB = !pitchPprovided ? pitchB(internal.width, internal.format, renderTarget) : pitchPprovided * internal.bytes;
- internal.pitchP = !pitchPprovided ? pitchP(internal.width, internal.format, renderTarget) : pitchPprovided;
- internal.sliceB = sliceB(internal.width, internal.height, internal.format, renderTarget);
- internal.sliceP = sliceP(internal.width, internal.height, internal.format, renderTarget);
+ internal.pitchB = !pitchPprovided ? pitchB(internal.width, border, internal.format, renderTarget) : pitchPprovided * internal.bytes;
+ internal.pitchP = !pitchPprovided ? pitchP(internal.width, border, internal.format, renderTarget) : pitchPprovided;
+ internal.sliceB = sliceB(internal.width, internal.height, border, internal.format, renderTarget);
+ internal.sliceP = sliceP(internal.width, internal.height, border, internal.format, renderTarget);
+ internal.border = (short)border;
internal.lock = LOCK_UNLOCKED;
internal.dirty = false;
- stencil.buffer = 0;
+ stencil.buffer = nullptr;
stencil.width = width;
stencil.height = height;
stencil.depth = depth;
- stencil.format = FORMAT_S8;
+ stencil.samples = (short)samples;
+ stencil.format = isStencil(format) ? FORMAT_S8 : FORMAT_NULL;
stencil.bytes = bytes(stencil.format);
- stencil.pitchB = pitchB(stencil.width, stencil.format, renderTarget);
- stencil.pitchP = pitchP(stencil.width, stencil.format, renderTarget);
- stencil.sliceB = sliceB(stencil.width, stencil.height, stencil.format, renderTarget);
- stencil.sliceP = sliceP(stencil.width, stencil.height, stencil.format, renderTarget);
+ stencil.pitchB = pitchB(stencil.width, 0, stencil.format, renderTarget);
+ stencil.pitchP = pitchP(stencil.width, 0, stencil.format, renderTarget);
+ stencil.sliceB = sliceB(stencil.width, stencil.height, 0, stencil.format, renderTarget);
+ stencil.sliceP = sliceP(stencil.width, stencil.height, 0, stencil.format, renderTarget);
+ stencil.border = 0;
stencil.lock = LOCK_UNLOCKED;
stencil.dirty = false;
- dirtyMipmaps = true;
+ dirtyContents = true;
paletteUsed = 0;
}
@@ -1337,7 +1392,7 @@
}
else
{
- external.buffer = allocateBuffer(external.width, external.height, external.depth, external.format);
+ external.buffer = allocateBuffer(external.width, external.height, external.depth, external.border, external.samples, external.format);
}
}
@@ -1358,7 +1413,7 @@
case LOCK_WRITEONLY:
case LOCK_READWRITE:
case LOCK_DISCARD:
- dirtyMipmaps = true;
+ dirtyContents = true;
break;
default:
ASSERT(false);
@@ -1389,7 +1444,7 @@
}
else
{
- internal.buffer = allocateBuffer(internal.width, internal.height, internal.depth, internal.format);
+ internal.buffer = allocateBuffer(internal.width, internal.height, internal.depth, internal.border, internal.samples, internal.format);
}
}
@@ -1437,7 +1492,7 @@
case LOCK_WRITEONLY:
case LOCK_READWRITE:
case LOCK_DISCARD:
- dirtyMipmaps = true;
+ dirtyContents = true;
break;
default:
ASSERT(false);
@@ -1460,11 +1515,16 @@
void *Surface::lockStencil(int x, int y, int front, Accessor client)
{
+ if(stencil.format == FORMAT_NULL)
+ {
+ return nullptr;
+ }
+
resource->lock(client);
if(!stencil.buffer)
{
- stencil.buffer = allocateBuffer(stencil.width, stencil.height, stencil.depth, stencil.format);
+ stencil.buffer = allocateBuffer(stencil.width, stencil.height, stencil.depth, stencil.border, stencil.samples, stencil.format);
}
return stencil.lockRect(x, y, front, LOCK_READWRITE); // FIXME
@@ -1516,12 +1576,13 @@
case FORMAT_X8B8G8R8UI: return 4;
case FORMAT_A8B8G8R8UI: return 4;
case FORMAT_A8B8G8R8: return 4;
- case FORMAT_R8I_SNORM: return 1;
- case FORMAT_G8R8I_SNORM: return 2;
- case FORMAT_X8B8G8R8I_SNORM: return 4;
- case FORMAT_A8B8G8R8I_SNORM: return 4;
+ case FORMAT_R8_SNORM: return 1;
+ case FORMAT_G8R8_SNORM: return 2;
+ case FORMAT_X8B8G8R8_SNORM: return 4;
+ case FORMAT_A8B8G8R8_SNORM: return 4;
case FORMAT_A2R10G10B10: return 4;
case FORMAT_A2B10G10R10: return 4;
+ case FORMAT_A2B10G10R10UI: return 4;
case FORMAT_G8R8I: return 2;
case FORMAT_G8R8: return 2;
case FORMAT_G16R16I: return 4;
@@ -1539,11 +1600,9 @@
case FORMAT_A32B32G32R32I: return 16;
case FORMAT_A32B32G32R32UI: return 16;
// Compressed formats
- #if S3TC_SUPPORT
case FORMAT_DXT1: return 2; // Column of four pixels
case FORMAT_DXT3: return 4; // Column of four pixels
case FORMAT_DXT5: return 4; // Column of four pixels
- #endif
case FORMAT_ATI1: return 2; // Column of four pixels
case FORMAT_ATI2: return 4; // Column of four pixels
case FORMAT_ETC1: return 2; // Column of four pixels
@@ -1608,13 +1667,16 @@
case FORMAT_R16F: return 2;
case FORMAT_G16R16F: return 4;
case FORMAT_B16G16R16F: return 6;
+ case FORMAT_X16B16G16R16F: return 8;
case FORMAT_A16B16G16R16F: return 8;
+ case FORMAT_X16B16G16R16F_UNSIGNED: return 8;
case FORMAT_A32F: return 4;
case FORMAT_R32F: return 4;
case FORMAT_G32R32F: return 8;
case FORMAT_B32G32R32F: return 12;
case FORMAT_X32B32G32R32F: return 16;
case FORMAT_A32B32G32R32F: return 16;
+ case FORMAT_X32B32G32R32F_UNSIGNED: return 16;
// Depth/stencil formats
case FORMAT_D16: return 2;
case FORMAT_D32: return 4;
@@ -1622,9 +1684,12 @@
case FORMAT_D24S8: return 4;
case FORMAT_D24FS8: return 4;
case FORMAT_D32F: return 4;
+ case FORMAT_D32FS8: return 4;
case FORMAT_D32F_COMPLEMENTARY: return 4;
+ case FORMAT_D32FS8_COMPLEMENTARY: return 4;
case FORMAT_D32F_LOCKABLE: return 4;
case FORMAT_D32FS8_TEXTURE: return 4;
+ case FORMAT_D32F_SHADOW: return 4;
case FORMAT_D32FS8_SHADOW: return 4;
case FORMAT_DF24S8: return 4;
case FORMAT_DF16S8: return 2;
@@ -1640,8 +1705,10 @@
return 0;
}
- int Surface::pitchB(int width, Format format, bool target)
+ int Surface::pitchB(int width, int border, Format format, bool target)
{
+ width += 2 * border;
+
if(target || isDepth(format) || isStencil(format))
{
width = align(width, 2);
@@ -1649,9 +1716,7 @@
switch(format)
{
- #if S3TC_SUPPORT
case FORMAT_DXT1:
- #endif
case FORMAT_ETC1:
case FORMAT_R11_EAC:
case FORMAT_SIGNED_R11_EAC:
@@ -1698,11 +1763,9 @@
case FORMAT_RGBA_ASTC_12x12_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR:
return 16 * ((width + 11) / 12);
- #if S3TC_SUPPORT
case FORMAT_DXT3:
case FORMAT_DXT5:
return 16 * ((width + 3) / 4); // 128 bit per 4x4 block, computed per 4 rows
- #endif
case FORMAT_ATI1:
return 2 * ((width + 3) / 4); // 64 bit per 4x4 block, computed per row
case FORMAT_ATI2:
@@ -1716,15 +1779,17 @@
}
}
- int Surface::pitchP(int width, Format format, bool target)
+ int Surface::pitchP(int width, int border, Format format, bool target)
{
int B = bytes(format);
- return B > 0 ? pitchB(width, format, target) / B : 0;
+ return B > 0 ? pitchB(width, border, format, target) / B : 0;
}
- int Surface::sliceB(int width, int height, Format format, bool target)
+ int Surface::sliceB(int width, int height, int border, Format format, bool target)
{
+ height += 2 * border;
+
if(target || isDepth(format) || isStencil(format))
{
height = ((height + 1) & ~1);
@@ -1732,11 +1797,9 @@
switch(format)
{
- #if S3TC_SUPPORT
case FORMAT_DXT1:
case FORMAT_DXT3:
case FORMAT_DXT5:
- #endif
case FORMAT_ETC1:
case FORMAT_R11_EAC:
case FORMAT_SIGNED_R11_EAC:
@@ -1752,7 +1815,7 @@
case FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR:
case FORMAT_RGBA_ASTC_5x4_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR:
- return pitchB(width, format, target) * ((height + 3) / 4); // Pitch computed per 4 rows
+ return pitchB(width, border, format, target) * ((height + 3) / 4); // Pitch computed per 4 rows
case FORMAT_RGBA_ASTC_5x5_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR:
case FORMAT_RGBA_ASTC_6x5_KHR:
@@ -1761,39 +1824,39 @@
case FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR:
case FORMAT_RGBA_ASTC_10x5_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR:
- return pitchB(width, format, target) * ((height + 4) / 5); // Pitch computed per 5 rows
+ return pitchB(width, border, format, target) * ((height + 4) / 5); // Pitch computed per 5 rows
case FORMAT_RGBA_ASTC_6x6_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR:
case FORMAT_RGBA_ASTC_8x6_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR:
case FORMAT_RGBA_ASTC_10x6_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR:
- return pitchB(width, format, target) * ((height + 5) / 6); // Pitch computed per 6 rows
+ return pitchB(width, border, format, target) * ((height + 5) / 6); // Pitch computed per 6 rows
case FORMAT_RGBA_ASTC_8x8_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR:
case FORMAT_RGBA_ASTC_10x8_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR:
- return pitchB(width, format, target) * ((height + 7) / 8); // Pitch computed per 8 rows
+ return pitchB(width, border, format, target) * ((height + 7) / 8); // Pitch computed per 8 rows
case FORMAT_RGBA_ASTC_10x10_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR:
case FORMAT_RGBA_ASTC_12x10_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR:
- return pitchB(width, format, target) * ((height + 9) / 10); // Pitch computed per 10 rows
+ return pitchB(width, border, format, target) * ((height + 9) / 10); // Pitch computed per 10 rows
case FORMAT_RGBA_ASTC_12x12_KHR:
case FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR:
- return pitchB(width, format, target) * ((height + 11) / 12); // Pitch computed per 12 rows
+ return pitchB(width, border, format, target) * ((height + 11) / 12); // Pitch computed per 12 rows
case FORMAT_ATI1:
case FORMAT_ATI2:
default:
- return pitchB(width, format, target) * height; // Pitch computed per row
+ return pitchB(width, border, format, target) * height; // Pitch computed per row
}
}
- int Surface::sliceP(int width, int height, Format format, bool target)
+ int Surface::sliceP(int width, int height, int border, Format format, bool target)
{
int B = bytes(format);
- return B > 0 ? sliceB(width, height, format, target) / B : 0;
+ return B > 0 ? sliceB(width, height, border, format, target) / B : 0;
}
void Surface::update(Buffer &destination, Buffer &source)
@@ -1813,11 +1876,9 @@
case FORMAT_X4R4G4B4: decodeX4R4G4B4(destination, source); break; // FIXME: Check destination format
case FORMAT_A4R4G4B4: decodeA4R4G4B4(destination, source); break; // FIXME: Check destination format
case FORMAT_P8: decodeP8(destination, source); break; // FIXME: Check destination format
- #if S3TC_SUPPORT
case FORMAT_DXT1: decodeDXT1(destination, source); break; // FIXME: Check destination format
case FORMAT_DXT3: decodeDXT3(destination, source); break; // FIXME: Check destination format
case FORMAT_DXT5: decodeDXT5(destination, source); break; // FIXME: Check destination format
- #endif
case FORMAT_ATI1: decodeATI1(destination, source); break; // FIXME: Check destination format
case FORMAT_ATI2: decodeATI2(destination, source); break; // FIXME: Check destination format
case FORMAT_R11_EAC: decodeEAC(destination, source, 1, false); break; // FIXME: Check destination format
@@ -1866,8 +1927,8 @@
void Surface::genericUpdate(Buffer &destination, Buffer &source)
{
- unsigned char *sourceSlice = (unsigned char*)source.buffer;
- unsigned char *destinationSlice = (unsigned char*)destination.buffer;
+ unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
+ unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_UPDATE);
int depth = min(destination.depth, source.depth);
int height = min(destination.height, source.height);
@@ -1907,24 +1968,31 @@
sourceSlice += source.sliceB;
destinationSlice += destination.sliceB;
}
+
+ source.unlockRect();
+ destination.unlockRect();
}
- void Surface::decodeR8G8B8(Buffer &destination, const Buffer &source)
+ void Surface::decodeR8G8B8(Buffer &destination, Buffer &source)
{
- unsigned char *sourceSlice = (unsigned char*)source.buffer;
- unsigned char *destinationSlice = (unsigned char*)destination.buffer;
+ unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
+ unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_UPDATE);
- for(int z = 0; z < destination.depth && z < source.depth; z++)
+ int depth = min(destination.depth, source.depth);
+ int height = min(destination.height, source.height);
+ int width = min(destination.width, source.width);
+
+ for(int z = 0; z < depth; z++)
{
unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice;
- for(int y = 0; y < destination.height && y < source.height; y++)
+ for(int y = 0; y < height; y++)
{
unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow;
- for(int x = 0; x < destination.width && x < source.width; x++)
+ for(int x = 0; x < width; x++)
{
unsigned int b = sourceElement[0];
unsigned int g = sourceElement[1];
@@ -1943,24 +2011,31 @@
sourceSlice += source.sliceB;
destinationSlice += destination.sliceB;
}
+
+ source.unlockRect();
+ destination.unlockRect();
}
- void Surface::decodeX1R5G5B5(Buffer &destination, const Buffer &source)
+ void Surface::decodeX1R5G5B5(Buffer &destination, Buffer &source)
{
- unsigned char *sourceSlice = (unsigned char*)source.buffer;
- unsigned char *destinationSlice = (unsigned char*)destination.buffer;
+ unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
+ unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_UPDATE);
- for(int z = 0; z < destination.depth && z < source.depth; z++)
+ int depth = min(destination.depth, source.depth);
+ int height = min(destination.height, source.height);
+ int width = min(destination.width, source.width);
+
+ for(int z = 0; z < depth; z++)
{
unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice;
- for(int y = 0; y < destination.height && y < source.height; y++)
+ for(int y = 0; y < height; y++)
{
unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow;
- for(int x = 0; x < destination.width && x < source.width; x++)
+ for(int x = 0; x < width; x++)
{
unsigned int xrgb = *(unsigned short*)sourceElement;
@@ -1981,24 +2056,31 @@
sourceSlice += source.sliceB;
destinationSlice += destination.sliceB;
}
+
+ source.unlockRect();
+ destination.unlockRect();
}
- void Surface::decodeA1R5G5B5(Buffer &destination, const Buffer &source)
+ void Surface::decodeA1R5G5B5(Buffer &destination, Buffer &source)
{
- unsigned char *sourceSlice = (unsigned char*)source.buffer;
- unsigned char *destinationSlice = (unsigned char*)destination.buffer;
+ unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
+ unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_UPDATE);
- for(int z = 0; z < destination.depth && z < source.depth; z++)
+ int depth = min(destination.depth, source.depth);
+ int height = min(destination.height, source.height);
+ int width = min(destination.width, source.width);
+
+ for(int z = 0; z < depth; z++)
{
unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice;
- for(int y = 0; y < destination.height && y < source.height; y++)
+ for(int y = 0; y < height; y++)
{
unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow;
- for(int x = 0; x < destination.width && x < source.width; x++)
+ for(int x = 0; x < width; x++)
{
unsigned int argb = *(unsigned short*)sourceElement;
@@ -2020,24 +2102,31 @@
sourceSlice += source.sliceB;
destinationSlice += destination.sliceB;
}
+
+ source.unlockRect();
+ destination.unlockRect();
}
- void Surface::decodeX4R4G4B4(Buffer &destination, const Buffer &source)
+ void Surface::decodeX4R4G4B4(Buffer &destination, Buffer &source)
{
- unsigned char *sourceSlice = (unsigned char*)source.buffer;
- unsigned char *destinationSlice = (unsigned char*)destination.buffer;
+ unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
+ unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_UPDATE);
- for(int z = 0; z < destination.depth && z < source.depth; z++)
+ int depth = min(destination.depth, source.depth);
+ int height = min(destination.height, source.height);
+ int width = min(destination.width, source.width);
+
+ for(int z = 0; z < depth; z++)
{
unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice;
- for(int y = 0; y < destination.height && y < source.height; y++)
+ for(int y = 0; y < height; y++)
{
unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow;
- for(int x = 0; x < destination.width && x < source.width; x++)
+ for(int x = 0; x < width; x++)
{
unsigned int xrgb = *(unsigned short*)sourceElement;
@@ -2058,24 +2147,31 @@
sourceSlice += source.sliceB;
destinationSlice += destination.sliceB;
}
+
+ source.unlockRect();
+ destination.unlockRect();
}
- void Surface::decodeA4R4G4B4(Buffer &destination, const Buffer &source)
+ void Surface::decodeA4R4G4B4(Buffer &destination, Buffer &source)
{
- unsigned char *sourceSlice = (unsigned char*)source.buffer;
- unsigned char *destinationSlice = (unsigned char*)destination.buffer;
+ unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
+ unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_UPDATE);
- for(int z = 0; z < destination.depth && z < source.depth; z++)
+ int depth = min(destination.depth, source.depth);
+ int height = min(destination.height, source.height);
+ int width = min(destination.width, source.width);
+
+ for(int z = 0; z < depth; z++)
{
unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice;
- for(int y = 0; y < destination.height && y < source.height; y++)
+ for(int y = 0; y < height; y++)
{
unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow;
- for(int x = 0; x < destination.width && x < source.width; x++)
+ for(int x = 0; x < width; x++)
{
unsigned int argb = *(unsigned short*)sourceElement;
@@ -2097,24 +2193,31 @@
sourceSlice += source.sliceB;
destinationSlice += destination.sliceB;
}
+
+ source.unlockRect();
+ destination.unlockRect();
}
- void Surface::decodeP8(Buffer &destination, const Buffer &source)
+ void Surface::decodeP8(Buffer &destination, Buffer &source)
{
- unsigned char *sourceSlice = (unsigned char*)source.buffer;
- unsigned char *destinationSlice = (unsigned char*)destination.buffer;
+ unsigned char *sourceSlice = (unsigned char*)source.lockRect(0, 0, 0, sw::LOCK_READONLY);
+ unsigned char *destinationSlice = (unsigned char*)destination.lockRect(0, 0, 0, sw::LOCK_UPDATE);
- for(int z = 0; z < destination.depth && z < source.depth; z++)
+ int depth = min(destination.depth, source.depth);
+ int height = min(destination.height, source.height);
+ int width = min(destination.width, source.width);
+
+ for(int z = 0; z < depth; z++)
{
unsigned char *sourceRow = sourceSlice;
unsigned char *destinationRow = destinationSlice;
- for(int y = 0; y < destination.height && y < source.height; y++)
+ for(int y = 0; y < height; y++)
{
unsigned char *sourceElement = sourceRow;
unsigned char *destinationElement = destinationRow;
- for(int x = 0; x < destination.width && x < source.width; x++)
+ for(int x = 0; x < width; x++)
{
unsigned int abgr = palette[*(unsigned char*)sourceElement];
@@ -2136,13 +2239,15 @@
sourceSlice += source.sliceB;
destinationSlice += destination.sliceB;
}
+
+ source.unlockRect();
+ destination.unlockRect();
}
-#if S3TC_SUPPORT
- void Surface::decodeDXT1(Buffer &internal, const Buffer &external)
+ void Surface::decodeDXT1(Buffer &internal, Buffer &external)
{
- unsigned int *destSlice = (unsigned int*)internal.buffer;
- const DXT1 *source = (const DXT1*)external.buffer;
+ unsigned int *destSlice = (unsigned int*)internal.lockRect(0, 0, 0, LOCK_UPDATE);
+ const DXT1 *source = (const DXT1*)external.lockRect(0, 0, 0, LOCK_READONLY);
for(int z = 0; z < external.depth; z++)
{
@@ -2199,12 +2304,15 @@
(byte*&)destSlice += internal.sliceB;
}
+
+ external.unlockRect();
+ internal.unlockRect();
}
- void Surface::decodeDXT3(Buffer &internal, const Buffer &external)
+ void Surface::decodeDXT3(Buffer &internal, Buffer &external)
{
- unsigned int *destSlice = (unsigned int*)internal.buffer;
- const DXT3 *source = (const DXT3*)external.buffer;
+ unsigned int *destSlice = (unsigned int*)internal.lockRect(0, 0, 0, LOCK_UPDATE);
+ const DXT3 *source = (const DXT3*)external.lockRect(0, 0, 0, LOCK_READONLY);
for(int z = 0; z < external.depth; z++)
{
@@ -2246,12 +2354,15 @@
(byte*&)destSlice += internal.sliceB;
}
+
+ external.unlockRect();
+ internal.unlockRect();
}
- void Surface::decodeDXT5(Buffer &internal, const Buffer &external)
+ void Surface::decodeDXT5(Buffer &internal, Buffer &external)
{
- unsigned int *destSlice = (unsigned int*)internal.buffer;
- const DXT5 *source = (const DXT5*)external.buffer;
+ unsigned int *destSlice = (unsigned int*)internal.lockRect(0, 0, 0, LOCK_UPDATE);
+ const DXT5 *source = (const DXT5*)external.lockRect(0, 0, 0, LOCK_READONLY);
for(int z = 0; z < external.depth; z++)
{
@@ -2317,13 +2428,15 @@
(byte*&)destSlice += internal.sliceB;
}
- }
-#endif
- void Surface::decodeATI1(Buffer &internal, const Buffer &external)
+ external.unlockRect();
+ internal.unlockRect();
+ }
+
+ void Surface::decodeATI1(Buffer &internal, Buffer &external)
{
- byte *destSlice = (byte*)internal.buffer;
- const ATI1 *source = (const ATI1*)external.buffer;
+ byte *destSlice = (byte*)internal.lockRect(0, 0, 0, LOCK_UPDATE);
+ const ATI1 *source = (const ATI1*)external.lockRect(0, 0, 0, LOCK_READONLY);
for(int z = 0; z < external.depth; z++)
{
@@ -2371,12 +2484,15 @@
destSlice += internal.sliceB;
}
+
+ external.unlockRect();
+ internal.unlockRect();
}
- void Surface::decodeATI2(Buffer &internal, const Buffer &external)
+ void Surface::decodeATI2(Buffer &internal, Buffer &external)
{
- word *destSlice = (word*)internal.buffer;
- const ATI2 *source = (const ATI2*)external.buffer;
+ word *destSlice = (word*)internal.lockRect(0, 0, 0, LOCK_UPDATE);
+ const ATI2 *source = (const ATI2*)external.lockRect(0, 0, 0, LOCK_READONLY);
for(int z = 0; z < external.depth; z++)
{
@@ -2451,12 +2567,17 @@
(byte*&)destSlice += internal.sliceB;
}
+
+ external.unlockRect();
+ internal.unlockRect();
}
- void Surface::decodeETC2(Buffer &internal, const Buffer &external, int nbAlphaBits, bool isSRGB)
+ void Surface::decodeETC2(Buffer &internal, Buffer &external, int nbAlphaBits, bool isSRGB)
{
- ETC_Decoder::Decode((const byte*)external.buffer, (byte*)internal.buffer, external.width, external.height, internal.width, internal.height, internal.pitchB, internal.bytes,
+ ETC_Decoder::Decode((const byte*)external.lockRect(0, 0, 0, LOCK_READONLY), (byte*)internal.lockRect(0, 0, 0, LOCK_UPDATE), external.width, external.height, internal.width, internal.height, internal.pitchB, internal.bytes,
(nbAlphaBits == 8) ? ETC_Decoder::ETC_RGBA : ((nbAlphaBits == 1) ? ETC_Decoder::ETC_RGB_PUNCHTHROUGH_ALPHA : ETC_Decoder::ETC_RGB));
+ external.unlockRect();
+ internal.unlockRect();
if(isSRGB)
{
@@ -2472,69 +2593,68 @@
}
// Perform sRGB conversion in place after decoding
- byte* src = (byte*)internal.buffer;
+ byte *src = (byte*)internal.lockRect(0, 0, 0, LOCK_READWRITE);
for(int y = 0; y < internal.height; y++)
{
- byte* srcRow = src + y * internal.pitchB;
+ byte *srcRow = src + y * internal.pitchB;
for(int x = 0; x < internal.width; x++)
{
- byte* srcPix = srcRow + x * internal.bytes;
+ byte *srcPix = srcRow + x * internal.bytes;
for(int i = 0; i < 3; i++)
{
srcPix[i] = sRGBtoLinearTable[srcPix[i]];
}
}
}
+ internal.unlockRect();
}
}
- void Surface::decodeEAC(Buffer &internal, const Buffer &external, int nbChannels, bool isSigned)
+ void Surface::decodeEAC(Buffer &internal, Buffer &external, int nbChannels, bool isSigned)
{
ASSERT(nbChannels == 1 || nbChannels == 2);
- ETC_Decoder::Decode((const byte*)external.buffer, (byte*)internal.buffer, external.width, external.height, internal.width, internal.height, internal.pitchB, internal.bytes,
+ byte *src = (byte*)internal.lockRect(0, 0, 0, LOCK_READWRITE);
+ ETC_Decoder::Decode((const byte*)external.lockRect(0, 0, 0, LOCK_READONLY), src, external.width, external.height, internal.width, internal.height, internal.pitchB, internal.bytes,
(nbChannels == 1) ? (isSigned ? ETC_Decoder::ETC_R_SIGNED : ETC_Decoder::ETC_R_UNSIGNED) : (isSigned ? ETC_Decoder::ETC_RG_SIGNED : ETC_Decoder::ETC_RG_UNSIGNED));
+ external.unlockRect();
- // FIXME: We convert signed data to float, until signed integer internal formats are supported
- // This code can be removed if signed ETC2 images are decoded to internal 8 bit signed R/RG formats
- if(isSigned)
+ // FIXME: We convert EAC data to float, until signed short internal formats are supported
+ // This code can be removed if ETC2 images are decoded to internal 16 bit signed R/RG formats
+ const float normalization = isSigned ? (1.0f / (8.0f * 127.875f)) : (1.0f / (8.0f * 255.875f));
+ for(int y = 0; y < internal.height; y++)
{
- sbyte* src = (sbyte*)internal.buffer;
-
- for(int y = 0; y < internal.height; y++)
+ byte* srcRow = src + y * internal.pitchB;
+ for(int x = internal.width - 1; x >= 0; x--)
{
- sbyte* srcRow = src + y * internal.pitchB;
- for(int x = internal.width - 1; x >= 0; x--)
+ int* srcPix = reinterpret_cast<int*>(srcRow + x * internal.bytes);
+ float* dstPix = reinterpret_cast<float*>(srcPix);
+ for(int c = nbChannels - 1; c >= 0; c--)
{
- int dx = x & 0xFFFFFFFC;
- int mx = x - dx;
- sbyte* srcPix = srcRow + dx * internal.bytes + mx * nbChannels;
- float* dstPix = (float*)(srcRow + x * internal.bytes);
- for(int c = nbChannels - 1; c >= 0; c--)
- {
- static const float normalization = 1.0f / 127.875f;
- dstPix[c] = clamp(static_cast<float>(srcPix[c]) * normalization, -1.0f, 1.0f);
- }
+ dstPix[c] = clamp(static_cast<float>(srcPix[c]) * normalization, -1.0f, 1.0f);
}
}
}
+
+ internal.unlockRect();
}
- void Surface::decodeASTC(Buffer &internal, const Buffer &external, int xBlockSize, int yBlockSize, int zBlockSize, bool isSRGB)
+ void Surface::decodeASTC(Buffer &internal, Buffer &external, int xBlockSize, int yBlockSize, int zBlockSize, bool isSRGB)
{
}
- unsigned int Surface::size(int width, int height, int depth, Format format)
+ unsigned int Surface::size(int width, int height, int depth, int border, int samples, Format format)
{
+ width += 2 * border;
+ height += 2 * border;
+
// Dimensions rounded up to multiples of 4, used for compressed formats
int width4 = align(width, 4);
int height4 = align(height, 4);
switch(format)
{
- #if S3TC_SUPPORT
case FORMAT_DXT1:
- #endif
case FORMAT_ATI1:
case FORMAT_ETC1:
case FORMAT_R11_EAC:
@@ -2544,10 +2664,8 @@
case FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
return width4 * height4 * depth / 2;
- #if S3TC_SUPPORT
case FORMAT_DXT3:
case FORMAT_DXT5:
- #endif
case FORMAT_ATI2:
case FORMAT_RG11_EAC:
case FORMAT_SIGNED_RG11_EAC:
@@ -2607,7 +2725,7 @@
return YSize + 2 * CSize;
}
default:
- return bytes(format) * width * height * depth;
+ return bytes(format) * width * height * depth * samples;
}
}
@@ -2621,6 +2739,7 @@
case FORMAT_D32F:
case FORMAT_D32F_COMPLEMENTARY:
case FORMAT_D32F_LOCKABLE:
+ case FORMAT_D32F_SHADOW:
return false;
case FORMAT_D24S8:
case FORMAT_D24FS8:
@@ -2629,6 +2748,8 @@
case FORMAT_DF16S8:
case FORMAT_D32FS8_TEXTURE:
case FORMAT_D32FS8_SHADOW:
+ case FORMAT_D32FS8:
+ case FORMAT_D32FS8_COMPLEMENTARY:
case FORMAT_INTZ:
return true;
default:
@@ -2646,11 +2767,14 @@
case FORMAT_D24S8:
case FORMAT_D24FS8:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_COMPLEMENTARY:
+ case FORMAT_D32FS8_COMPLEMENTARY:
case FORMAT_D32F_LOCKABLE:
case FORMAT_DF24S8:
case FORMAT_DF16S8:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_INTZ:
return true;
@@ -2671,7 +2795,9 @@
case FORMAT_D24S8:
case FORMAT_D24FS8:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_COMPLEMENTARY:
+ case FORMAT_D32FS8_COMPLEMENTARY:
case FORMAT_DF24S8:
case FORMAT_DF16S8:
case FORMAT_INTZ:
@@ -2681,6 +2807,7 @@
return true;
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
default:
break;
@@ -2723,10 +2850,11 @@
case FORMAT_G8R8I:
case FORMAT_G8R8:
case FORMAT_A2B10G10R10:
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_A2B10G10R10UI:
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_R16I:
case FORMAT_R16UI:
case FORMAT_G16R16I:
@@ -2765,16 +2893,22 @@
case FORMAT_R16F:
case FORMAT_G16R16F:
case FORMAT_B16G16R16F:
+ case FORMAT_X16B16G16R16F:
case FORMAT_A16B16G16R16F:
+ case FORMAT_X16B16G16R16F_UNSIGNED:
case FORMAT_R32F:
case FORMAT_G32R32F:
case FORMAT_B32G32R32F:
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_COMPLEMENTARY:
+ case FORMAT_D32FS8_COMPLEMENTARY:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_L16F:
case FORMAT_A16L16F:
@@ -2804,6 +2938,7 @@
case FORMAT_SRGB8_A8:
case FORMAT_G8R8:
case FORMAT_A2B10G10R10:
+ case FORMAT_A2B10G10R10UI:
case FORMAT_R16UI:
case FORMAT_G16R16:
case FORMAT_G16R16UI:
@@ -2814,14 +2949,18 @@
case FORMAT_G32R32UI:
case FORMAT_X32B32G32R32UI:
case FORMAT_A32B32G32R32UI:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_R8UI:
case FORMAT_G8R8UI:
case FORMAT_X8B8G8R8UI:
case FORMAT_A8B8G8R8UI:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_COMPLEMENTARY:
+ case FORMAT_D32FS8_COMPLEMENTARY:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_A8:
case FORMAT_R8:
@@ -2835,7 +2974,7 @@
case FORMAT_A8B8G8R8I:
case FORMAT_A16B16G16R16I:
case FORMAT_A32B32G32R32I:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_Q8W8V8U8:
case FORMAT_Q16W16V16U16:
case FORMAT_A32B32G32R32F:
@@ -2844,7 +2983,7 @@
case FORMAT_R8I:
case FORMAT_R16I:
case FORMAT_R32I:
- case FORMAT_R8I_SNORM:
+ case FORMAT_R8_SNORM:
return component >= 1;
case FORMAT_V8U8:
case FORMAT_X8L8V8U8:
@@ -2853,7 +2992,7 @@
case FORMAT_G8R8I:
case FORMAT_G16R16I:
case FORMAT_G32R32I:
- case FORMAT_G8R8I_SNORM:
+ case FORMAT_G8R8_SNORM:
return component >= 2;
case FORMAT_A16W16V16U16:
case FORMAT_B32G32R32F:
@@ -2861,7 +3000,7 @@
case FORMAT_X8B8G8R8I:
case FORMAT_X16B16G16R16I:
case FORMAT_X32B32G32R32I:
- case FORMAT_X8B8G8R8I_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
return component >= 3;
default:
ASSERT(false);
@@ -2888,11 +3027,9 @@
case FORMAT_X1R5G5B5:
case FORMAT_A1R5G5B5:
case FORMAT_A4R4G4B4:
- #if S3TC_SUPPORT
case FORMAT_DXT1:
case FORMAT_DXT3:
case FORMAT_DXT5:
- #endif
case FORMAT_ATI1:
case FORMAT_ATI2:
return true;
@@ -2920,15 +3057,25 @@
}
}
+ bool Surface::isSRGBformat(Format format)
+ {
+ switch(format)
+ {
+ case FORMAT_SRGB8_X8:
+ case FORMAT_SRGB8_A8:
+ return true;
+ default:
+ return false;
+ }
+ }
+
bool Surface::isCompressed(Format format)
{
switch(format)
{
- #if S3TC_SUPPORT
case FORMAT_DXT1:
case FORMAT_DXT3:
case FORMAT_DXT5:
- #endif
case FORMAT_ATI1:
case FORMAT_ATI2:
case FORMAT_ETC1:
@@ -3050,15 +3197,16 @@
case FORMAT_A8B8G8R8: return 4;
case FORMAT_G8R8I: return 2;
case FORMAT_G8R8: return 2;
- case FORMAT_R8I_SNORM: return 1;
- case FORMAT_G8R8I_SNORM: return 2;
- case FORMAT_X8B8G8R8I_SNORM:return 3;
- case FORMAT_A8B8G8R8I_SNORM:return 4;
+ case FORMAT_R8_SNORM: return 1;
+ case FORMAT_G8R8_SNORM: return 2;
+ case FORMAT_X8B8G8R8_SNORM:return 3;
+ case FORMAT_A8B8G8R8_SNORM:return 4;
case FORMAT_R8UI: return 1;
case FORMAT_G8R8UI: return 2;
case FORMAT_X8B8G8R8UI: return 3;
case FORMAT_A8B8G8R8UI: return 4;
case FORMAT_A2B10G10R10: return 4;
+ case FORMAT_A2B10G10R10UI: return 4;
case FORMAT_G16R16I: return 2;
case FORMAT_G16R16UI: return 2;
case FORMAT_G16R16: return 2;
@@ -3083,9 +3231,12 @@
case FORMAT_G32R32F: return 2;
case FORMAT_X32B32G32R32F: return 3;
case FORMAT_A32B32G32R32F: return 4;
+ case FORMAT_X32B32G32R32F_UNSIGNED: return 3;
case FORMAT_D32F: return 1;
+ case FORMAT_D32FS8: return 1;
case FORMAT_D32F_LOCKABLE: return 1;
case FORMAT_D32FS8_TEXTURE: return 1;
+ case FORMAT_D32F_SHADOW: return 1;
case FORMAT_D32FS8_SHADOW: return 1;
case FORMAT_A8: return 1;
case FORMAT_R8I: return 1;
@@ -3107,7 +3258,7 @@
return 1;
}
- void *Surface::allocateBuffer(int width, int height, int depth, Format format)
+ void *Surface::allocateBuffer(int width, int height, int depth, int border, int samples, Format format)
{
// Render targets require 2x2 quads
int width2 = (width + 1) & ~1;
@@ -3116,7 +3267,7 @@
// FIXME: Unpacking byte4 to short4 in the sampler currently involves reading 8 bytes,
// and stencil operations also read 8 bytes per four 8-bit stencil values,
// so we have to allocate 4 extra bytes to avoid buffer overruns.
- return allocate(size(width2, height2, depth, format) + 4);
+ return allocate(size(width2, height2, depth, border, samples, format) + 4);
}
void Surface::memfill4(void *buffer, int pattern, int bytes)
@@ -3222,24 +3373,22 @@
const bool entire = x0 == 0 && y0 == 0 && width == internal.width && height == internal.height;
const Lock lock = entire ? LOCK_DISCARD : LOCK_WRITEONLY;
- int width2 = (internal.width + 1) & ~1;
-
int x1 = x0 + width;
int y1 = y0 + height;
- if(internal.format == FORMAT_D32F_LOCKABLE ||
- internal.format == FORMAT_D32FS8_TEXTURE ||
- internal.format == FORMAT_D32FS8_SHADOW)
+ if(!hasQuadLayout(internal.format))
{
- float *target = (float*)lockInternal(0, 0, 0, lock, PUBLIC) + x0 + width2 * y0;
+ float *target = (float*)lockInternal(x0, y0, 0, lock, PUBLIC);
- for(int z = 0; z < internal.depth; z++)
+ for(int z = 0; z < internal.samples; z++)
{
+ float *row = target;
for(int y = y0; y < y1; y++)
{
- memfill4(target, (int&)depth, 4 * width);
- target += width2;
+ memfill4(row, (int&)depth, width * sizeof(float));
+ row += internal.pitchP;
}
+ target += internal.sliceP;
}
unlockInternal();
@@ -3258,11 +3407,11 @@
int evenX0 = ((x0 + 1) & ~1) * 2;
int evenBytes = (oddX1 - evenX0) * sizeof(float);
- for(int z = 0; z < internal.depth; z++)
+ for(int z = 0; z < internal.samples; z++)
{
for(int y = y0; y < y1; y++)
{
- float *target = buffer + (y & ~1) * width2 + (y & 1) * 2;
+ float *target = buffer + (y & ~1) * internal.pitchP + (y & 1) * 2;
if((y & 1) == 0 && y + 1 < y1) // Fill quad line at once
{
@@ -3344,8 +3493,6 @@
if(y0 < 0) {height += y0; y0 = 0;}
if(y0 + height > internal.height) height = internal.height - y0;
- int width2 = (internal.width + 1) & ~1;
-
int x1 = x0 + width;
int y1 = y0 + height;
@@ -3362,11 +3509,11 @@
char *buffer = (char*)lockStencil(0, 0, 0, PUBLIC);
// Stencil buffers are assumed to use quad layout
- for(int z = 0; z < stencil.depth; z++)
+ for(int z = 0; z < stencil.samples; z++)
{
for(int y = y0; y < y1; y++)
{
- char *target = buffer + (y & ~1) * width2 + (y & 1) * 2;
+ char *target = buffer + (y & ~1) * stencil.pitchP + (y & 1) * 2;
if((y & 1) == 0 && y + 1 < y1 && mask == 0xFF) // Fill quad line at once
{
@@ -3388,8 +3535,9 @@
}
else
{
- for(int x = x0, i = oddX0; x < x1; x++, i = (x & ~1) * 2 + (x & 1))
+ for(int x = x0; x < x1; x++)
{
+ int i = (x & ~1) * 2 + (x & 1);
target[i] = maskedS | (target[i] & invMask);
}
}
@@ -3459,7 +3607,7 @@
}
}
- void Surface::copyInternal(const Surface* source, int x, int y, float srcX, float srcY, bool filter)
+ void Surface::copyInternal(const Surface *source, int x, int y, float srcX, float srcY, bool filter)
{
ASSERT(internal.lock != LOCK_UNLOCKED && source && source->internal.lock != LOCK_UNLOCKED);
@@ -3467,17 +3615,17 @@
if(!filter)
{
- color = source->internal.read((int)srcX, (int)srcY);
+ color = source->internal.read((int)srcX, (int)srcY, 0);
}
else // Bilinear filtering
{
- color = source->internal.sample(srcX, srcY);
+ color = source->internal.sample(srcX, srcY, 0);
}
internal.write(x, y, color);
}
- void Surface::copyInternal(const Surface* source, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter)
+ void Surface::copyInternal(const Surface *source, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter)
{
ASSERT(internal.lock != LOCK_UNLOCKED && source && source->internal.lock != LOCK_UNLOCKED);
@@ -3495,6 +3643,81 @@
internal.write(x, y, z, color);
}
+ void Surface::copyCubeEdge(Edge dstEdge, Surface *src, Edge srcEdge)
+ {
+ Surface *dst = this;
+
+ // Figure out if the edges to be copied in reverse order respectively from one another
+ // The copy should be reversed whenever the same edges are contiguous or if we're
+ // copying top <-> right or bottom <-> left. This is explained by the layout, which is:
+ //
+ // | +y |
+ // | -x | +z | +x | -z |
+ // | -y |
+
+ bool reverse = (srcEdge == dstEdge) ||
+ ((srcEdge == TOP) && (dstEdge == RIGHT)) ||
+ ((srcEdge == RIGHT) && (dstEdge == TOP)) ||
+ ((srcEdge == BOTTOM) && (dstEdge == LEFT)) ||
+ ((srcEdge == LEFT) && (dstEdge == BOTTOM));
+
+ int srcBytes = src->bytes(src->Surface::getInternalFormat());
+ int srcPitch = src->getInternalPitchB();
+ int dstBytes = dst->bytes(dst->Surface::getInternalFormat());
+ int dstPitch = dst->getInternalPitchB();
+
+ int srcW = src->getWidth();
+ int srcH = src->getHeight();
+ int dstW = dst->getWidth();
+ int dstH = dst->getHeight();
+
+ ASSERT(srcW == srcH && dstW == dstH && srcW == dstW && srcBytes == dstBytes);
+
+ // Src is expressed in the regular [0, width-1], [0, height-1] space
+ int srcDelta = ((srcEdge == TOP) || (srcEdge == BOTTOM)) ? srcBytes : srcPitch;
+ int srcStart = ((srcEdge == BOTTOM) ? srcPitch * (srcH - 1) : ((srcEdge == RIGHT) ? srcBytes * (srcW - 1) : 0));
+
+ // Dst contains borders, so it is expressed in the [-1, width+1], [-1, height+1] space
+ int dstDelta = (((dstEdge == TOP) || (dstEdge == BOTTOM)) ? dstBytes : dstPitch) * (reverse ? -1 : 1);
+ int dstStart = ((dstEdge == BOTTOM) ? dstPitch * (dstH + 1) : ((dstEdge == RIGHT) ? dstBytes * (dstW + 1) : 0)) + (reverse ? dstW * -dstDelta : dstDelta);
+
+ char *srcBuf = (char*)src->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PRIVATE) + srcStart;
+ char *dstBuf = (char*)dst->lockInternal(-1, -1, 0, sw::LOCK_READWRITE, sw::PRIVATE) + dstStart;
+
+ for(int i = 0; i < srcW; ++i, dstBuf += dstDelta, srcBuf += srcDelta)
+ {
+ memcpy(dstBuf, srcBuf, srcBytes);
+ }
+
+ if(dstEdge == LEFT || dstEdge == RIGHT)
+ {
+ // TOP and BOTTOM are already set, let's average out the corners
+ int x0 = (dstEdge == RIGHT) ? dstW : -1;
+ int y0 = -1;
+ int x1 = (dstEdge == RIGHT) ? dstW - 1 : 0;
+ int y1 = 0;
+ dst->computeCubeCorner(x0, y0, x1, y1);
+ y0 = dstH;
+ y1 = dstH - 1;
+ dst->computeCubeCorner(x0, y0, x1, y1);
+ }
+
+ src->unlockInternal();
+ dst->unlockInternal();
+ }
+
+ void Surface::computeCubeCorner(int x0, int y0, int x1, int y1)
+ {
+ ASSERT(internal.lock != LOCK_UNLOCKED);
+
+ sw::Color<float> color = internal.read(x0, y1);
+ color += internal.read(x1, y0);
+ color += internal.read(x1, y1);
+ color *= (1.0f / 3.0f);
+
+ internal.write(x0, y0, color);
+ }
+
bool Surface::hasStencil() const
{
return isStencil(external.format);
@@ -3515,14 +3738,14 @@
return renderTarget;
}
- bool Surface::hasDirtyMipmaps() const
+ bool Surface::hasDirtyContents() const
{
- return dirtyMipmaps;
+ return dirtyContents;
}
- void Surface::cleanMipmaps()
+ void Surface::markContentsClean()
{
- dirtyMipmaps = false;
+ dirtyContents = false;
}
Resource *Surface::getResource()
@@ -3537,7 +3760,9 @@
external.height == internal.height &&
external.depth == internal.depth &&
external.pitchB == internal.pitchB &&
- external.sliceB == internal.sliceB;
+ external.sliceB == internal.sliceB &&
+ external.border == internal.border &&
+ external.samples == internal.samples;
}
Format Surface::selectInternalFormat(Format format) const
@@ -3558,8 +3783,8 @@
return FORMAT_R8I;
case FORMAT_R8UI:
return FORMAT_R8UI;
- case FORMAT_R8I_SNORM:
- return FORMAT_R8I_SNORM;
+ case FORMAT_R8_SNORM:
+ return FORMAT_R8_SNORM;
case FORMAT_R8:
return FORMAT_R8;
case FORMAT_R16I:
@@ -3571,27 +3796,33 @@
case FORMAT_R32UI:
return FORMAT_R32UI;
case FORMAT_X16B16G16R16I:
+ return FORMAT_X16B16G16R16I;
case FORMAT_A16B16G16R16I:
return FORMAT_A16B16G16R16I;
case FORMAT_X16B16G16R16UI:
+ return FORMAT_X16B16G16R16UI;
case FORMAT_A16B16G16R16UI:
return FORMAT_A16B16G16R16UI;
case FORMAT_A2R10G10B10:
case FORMAT_A2B10G10R10:
case FORMAT_A16B16G16R16:
return FORMAT_A16B16G16R16;
+ case FORMAT_A2B10G10R10UI:
+ return FORMAT_A16B16G16R16UI;
case FORMAT_X32B32G32R32I:
+ return FORMAT_X32B32G32R32I;
case FORMAT_A32B32G32R32I:
return FORMAT_A32B32G32R32I;
case FORMAT_X32B32G32R32UI:
+ return FORMAT_X32B32G32R32UI;
case FORMAT_A32B32G32R32UI:
return FORMAT_A32B32G32R32UI;
case FORMAT_G8R8I:
return FORMAT_G8R8I;
case FORMAT_G8R8UI:
return FORMAT_G8R8UI;
- case FORMAT_G8R8I_SNORM:
- return FORMAT_G8R8I_SNORM;
+ case FORMAT_G8R8_SNORM:
+ return FORMAT_G8R8_SNORM;
case FORMAT_G8R8:
return FORMAT_G8R8;
case FORMAT_G16R16I:
@@ -3617,8 +3848,8 @@
return FORMAT_A8B8G8R8I;
case FORMAT_A8B8G8R8UI:
return FORMAT_A8B8G8R8UI;
- case FORMAT_A8B8G8R8I_SNORM:
- return FORMAT_A8B8G8R8I_SNORM;
+ case FORMAT_A8B8G8R8_SNORM:
+ return FORMAT_A8B8G8R8_SNORM;
case FORMAT_R5G5B5A1:
case FORMAT_R4G4B4A4:
case FORMAT_A8B8G8R8:
@@ -3642,8 +3873,8 @@
return FORMAT_X8B8G8R8I;
case FORMAT_X8B8G8R8UI:
return FORMAT_X8B8G8R8UI;
- case FORMAT_X8B8G8R8I_SNORM:
- return FORMAT_X8B8G8R8I_SNORM;
+ case FORMAT_X8B8G8R8_SNORM:
+ return FORMAT_X8B8G8R8_SNORM;
case FORMAT_B8G8R8:
case FORMAT_X8B8G8R8:
return FORMAT_X8B8G8R8;
@@ -3652,11 +3883,9 @@
case FORMAT_SRGB8_A8:
return FORMAT_SRGB8_A8;
// Compressed formats
- #if S3TC_SUPPORT
case FORMAT_DXT1:
case FORMAT_DXT3:
case FORMAT_DXT5:
- #endif
case FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case FORMAT_RGBA8_ETC2_EAC:
@@ -3693,13 +3922,13 @@
// ASTC supports HDR, so a floating point format is required to represent it properly
return FORMAT_A32B32G32R32F; // FIXME: 16FP is probably sufficient, but it's currently unsupported
case FORMAT_ATI1:
- case FORMAT_R11_EAC:
return FORMAT_R8;
+ case FORMAT_R11_EAC:
case FORMAT_SIGNED_R11_EAC:
return FORMAT_R32F; // FIXME: Signed 8bit format would be sufficient
case FORMAT_ATI2:
- case FORMAT_RG11_EAC:
return FORMAT_G8R8;
+ case FORMAT_RG11_EAC:
case FORMAT_SIGNED_RG11_EAC:
return FORMAT_G32R32F; // FIXME: Signed 8bit format would be sufficient
case FORMAT_ETC1:
@@ -3719,13 +3948,16 @@
case FORMAT_R16F: return FORMAT_R32F;
case FORMAT_G16R16F: return FORMAT_G32R32F;
case FORMAT_B16G16R16F: return FORMAT_X32B32G32R32F;
+ case FORMAT_X16B16G16R16F: return FORMAT_X32B32G32R32F;
case FORMAT_A16B16G16R16F: return FORMAT_A32B32G32R32F;
+ case FORMAT_X16B16G16R16F_UNSIGNED: return FORMAT_X32B32G32R32F_UNSIGNED;
case FORMAT_A32F: return FORMAT_A32B32G32R32F;
case FORMAT_R32F: return FORMAT_R32F;
case FORMAT_G32R32F: return FORMAT_G32R32F;
case FORMAT_B32G32R32F: return FORMAT_X32B32G32R32F;
case FORMAT_X32B32G32R32F: return FORMAT_X32B32G32R32F;
case FORMAT_A32B32G32R32F: return FORMAT_A32B32G32R32F;
+ case FORMAT_X32B32G32R32F_UNSIGNED: return FORMAT_X32B32G32R32F_UNSIGNED;
// Luminance formats
case FORMAT_L8: return FORMAT_L8;
case FORMAT_A4L4: return FORMAT_A8L8;
@@ -3739,11 +3971,9 @@
case FORMAT_D16:
case FORMAT_D32:
case FORMAT_D24X8:
- case FORMAT_D24S8:
- case FORMAT_D24FS8:
if(hasParent) // Texture
{
- return FORMAT_D32FS8_SHADOW;
+ return FORMAT_D32F_SHADOW;
}
else if(complementaryDepthBuffer)
{
@@ -3753,12 +3983,29 @@
{
return FORMAT_D32F;
}
+ case FORMAT_D24S8:
+ case FORMAT_D24FS8:
+ if(hasParent) // Texture
+ {
+ return FORMAT_D32FS8_SHADOW;
+ }
+ else if(complementaryDepthBuffer)
+ {
+ return FORMAT_D32FS8_COMPLEMENTARY;
+ }
+ else
+ {
+ return FORMAT_D32FS8;
+ }
case FORMAT_D32F: return FORMAT_D32F;
+ case FORMAT_D32FS8: return FORMAT_D32FS8;
case FORMAT_D32F_LOCKABLE: return FORMAT_D32F_LOCKABLE;
case FORMAT_D32FS8_TEXTURE: return FORMAT_D32FS8_TEXTURE;
case FORMAT_INTZ: return FORMAT_D32FS8_TEXTURE;
case FORMAT_DF24S8: return FORMAT_D32FS8_SHADOW;
case FORMAT_DF16S8: return FORMAT_D32FS8_SHADOW;
+ case FORMAT_S8: return FORMAT_S8;
+ // YUV formats
case FORMAT_YV12_BT601: return FORMAT_YV12_BT601;
case FORMAT_YV12_BT709: return FORMAT_YV12_BT709;
case FORMAT_YV12_JFIF: return FORMAT_YV12_JFIF;
@@ -3777,11 +4024,13 @@
void Surface::resolve()
{
- if(internal.depth <= 1 || !internal.dirty || !renderTarget || internal.format == FORMAT_NULL)
+ if(internal.samples <= 1 || !internal.dirty || !renderTarget || internal.format == FORMAT_NULL)
{
return;
}
+ ASSERT(internal.depth == 1); // Unimplemented
+
void *source = internal.lockRect(0, 0, 0, LOCK_READWRITE);
int width = internal.width;
@@ -3813,7 +4062,7 @@
#if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE2() && (width % 4) == 0)
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -3831,7 +4080,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -3855,7 +4104,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -3891,7 +4140,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -3958,7 +4207,7 @@
{
#define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7F7F7F7F) + (((x) ^ (y)) & 0x01010101))
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -3976,7 +4225,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -4000,7 +4249,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -4036,7 +4285,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -4107,7 +4356,7 @@
#if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE2() && (width % 4) == 0)
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -4125,7 +4374,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -4149,7 +4398,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -4185,7 +4434,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -4252,7 +4501,7 @@
{
#define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7FFF7FFF) + (((x) ^ (y)) & 0x00010001))
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -4270,7 +4519,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -4294,7 +4543,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -4330,7 +4579,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -4400,7 +4649,7 @@
#if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE2() && (width % 2) == 0)
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -4418,7 +4667,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -4442,7 +4691,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -4478,7 +4727,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -4545,7 +4794,7 @@
{
#define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7FFF7FFF) + (((x) ^ (y)) & 0x00010001))
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -4563,7 +4812,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -4587,7 +4836,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -4623,7 +4872,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -4693,7 +4942,7 @@
#if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE() && (width % 4) == 0)
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -4712,7 +4961,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -4737,7 +4986,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -4774,7 +5023,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -4840,7 +5089,7 @@
else
#endif
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -4859,7 +5108,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -4884,7 +5133,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -4921,7 +5170,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -4990,7 +5239,7 @@
#if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE() && (width % 2) == 0)
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -5009,7 +5258,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -5034,7 +5283,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -5071,7 +5320,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -5137,7 +5386,7 @@
else
#endif
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -5156,7 +5405,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -5181,7 +5430,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -5218,7 +5467,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -5282,12 +5531,14 @@
else ASSERT(false);
}
}
- else if(internal.format == FORMAT_A32B32G32R32F || internal.format == FORMAT_X32B32G32R32F)
+ else if(internal.format == FORMAT_A32B32G32R32F ||
+ internal.format == FORMAT_X32B32G32R32F ||
+ internal.format == FORMAT_X32B32G32R32F_UNSIGNED)
{
#if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE())
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -5306,7 +5557,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -5331,7 +5582,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -5368,7 +5619,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -5434,7 +5685,7 @@
else
#endif
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -5453,7 +5704,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -5478,7 +5729,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -5515,7 +5766,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -5584,7 +5835,7 @@
#if defined(__i386__) || defined(__x86_64__)
if(CPUID::supportsSSE2() && (width % 8) == 0)
{
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -5613,7 +5864,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -5654,7 +5905,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -5719,7 +5970,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
@@ -5839,7 +6090,7 @@
{
#define AVERAGE(x, y) (((x) & (y)) + ((((x) ^ (y)) >> 1) & 0x7BEF) + (((x) ^ (y)) & 0x0821))
- if(internal.depth == 2)
+ if(internal.samples == 2)
{
for(int y = 0; y < height; y++)
{
@@ -5857,7 +6108,7 @@
source1 += pitch;
}
}
- else if(internal.depth == 4)
+ else if(internal.samples == 4)
{
for(int y = 0; y < height; y++)
{
@@ -5881,7 +6132,7 @@
source3 += pitch;
}
}
- else if(internal.depth == 8)
+ else if(internal.samples == 8)
{
for(int y = 0; y < height; y++)
{
@@ -5917,7 +6168,7 @@
source7 += pitch;
}
}
- else if(internal.depth == 16)
+ else if(internal.samples == 16)
{
for(int y = 0; y < height; y++)
{
diff --git a/src/Renderer/Surface.hpp b/src/Renderer/Surface.hpp
index 6418c08..bff1b7d 100644
--- a/src/Renderer/Surface.hpp
+++ b/src/Renderer/Surface.hpp
@@ -23,31 +23,43 @@
{
class Resource;
- struct Rect
+ template <typename T> struct RectT
{
- Rect() {}
- Rect(int x0i, int y0i, int x1i, int y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {}
+ RectT() {}
+ RectT(T x0i, T y0i, T x1i, T y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {}
- void clip(int minX, int minY, int maxX, int maxY);
+ void clip(T minX, T minY, T maxX, T maxY)
+ {
+ x0 = clamp(x0, minX, maxX);
+ y0 = clamp(y0, minY, maxY);
+ x1 = clamp(x1, minX, maxX);
+ y1 = clamp(y1, minY, maxY);
+ }
- int width() const { return x1 - x0; }
- int height() const { return y1 - y0; }
+ T width() const { return x1 - x0; }
+ T height() const { return y1 - y0; }
- int x0; // Inclusive
- int y0; // Inclusive
- int x1; // Exclusive
- int y1; // Exclusive
+ T x0; // Inclusive
+ T y0; // Inclusive
+ T x1; // Exclusive
+ T y1; // Exclusive
};
- struct SliceRect : public Rect
+ typedef RectT<int> Rect;
+ typedef RectT<float> RectF;
+
+ template<typename T> struct SliceRectT : public RectT<T>
{
- SliceRect() : slice(0) {}
- SliceRect(const Rect& rect) : Rect(rect), slice(0) {}
- SliceRect(const Rect& rect, int s) : Rect(rect), slice(s) {}
- SliceRect(int x0, int y0, int x1, int y1, int s) : Rect(x0, y0, x1, y1), slice(s) {}
+ SliceRectT() : slice(0) {}
+ SliceRectT(const RectT<T>& rect) : RectT<T>(rect), slice(0) {}
+ SliceRectT(const RectT<T>& rect, int s) : RectT<T>(rect), slice(s) {}
+ SliceRectT(T x0, T y0, T x1, T y1, int s) : RectT<T>(x0, y0, x1, y1), slice(s) {}
int slice;
};
+ typedef SliceRectT<int> SliceRect;
+ typedef SliceRectT<float> SliceRectF;
+
enum Format : unsigned char
{
FORMAT_NULL,
@@ -55,8 +67,8 @@
FORMAT_A8,
FORMAT_R8I,
FORMAT_R8UI,
- FORMAT_R8I_SNORM,
- FORMAT_R8, // UI_SNORM
+ FORMAT_R8_SNORM,
+ FORMAT_R8,
FORMAT_R16I,
FORMAT_R16UI,
FORMAT_R32I,
@@ -73,12 +85,12 @@
FORMAT_A8R8G8B8,
FORMAT_X8B8G8R8I,
FORMAT_X8B8G8R8UI,
- FORMAT_X8B8G8R8I_SNORM,
- FORMAT_X8B8G8R8, // UI_SNORM
+ FORMAT_X8B8G8R8_SNORM,
+ FORMAT_X8B8G8R8,
FORMAT_A8B8G8R8I,
FORMAT_A8B8G8R8UI,
- FORMAT_A8B8G8R8I_SNORM,
- FORMAT_A8B8G8R8, // UI_SNORM
+ FORMAT_A8B8G8R8_SNORM,
+ FORMAT_A8B8G8R8,
FORMAT_SRGB8_X8,
FORMAT_SRGB8_A8,
FORMAT_X1R5G5B5,
@@ -86,16 +98,17 @@
FORMAT_R5G5B5A1,
FORMAT_G8R8I,
FORMAT_G8R8UI,
- FORMAT_G8R8I_SNORM,
- FORMAT_G8R8, // UI_SNORM
- FORMAT_G16R16, // D3D format
+ FORMAT_G8R8_SNORM,
+ FORMAT_G8R8,
+ FORMAT_G16R16,
FORMAT_G16R16I,
FORMAT_G16R16UI,
FORMAT_G32R32I,
FORMAT_G32R32UI,
FORMAT_A2R10G10B10,
FORMAT_A2B10G10R10,
- FORMAT_A16B16G16R16, // D3D format
+ FORMAT_A2B10G10R10UI,
+ FORMAT_A16B16G16R16,
FORMAT_X16B16G16R16I,
FORMAT_X16B16G16R16UI,
FORMAT_A16B16G16R16I,
@@ -157,13 +170,16 @@
FORMAT_R16F,
FORMAT_G16R16F,
FORMAT_B16G16R16F,
+ FORMAT_X16B16G16R16F,
FORMAT_A16B16G16R16F,
+ FORMAT_X16B16G16R16F_UNSIGNED,
FORMAT_A32F,
FORMAT_R32F,
FORMAT_G32R32F,
FORMAT_B32G32R32F,
FORMAT_X32B32G32R32F,
FORMAT_A32B32G32R32F,
+ FORMAT_X32B32G32R32F_UNSIGNED,
// Bump map formats
FORMAT_V8U8,
FORMAT_L6V5U5,
@@ -189,9 +205,12 @@
FORMAT_D24S8,
FORMAT_D24FS8,
FORMAT_D32F, // Quad layout
+ FORMAT_D32FS8, // Quad layout
FORMAT_D32F_COMPLEMENTARY, // Quad layout, 1 - z
+ FORMAT_D32FS8_COMPLEMENTARY, // Quad layout, 1 - z
FORMAT_D32F_LOCKABLE, // Linear layout
FORMAT_D32FS8_TEXTURE, // Linear layout, no PCF
+ FORMAT_D32F_SHADOW, // Linear layout, PCF
FORMAT_D32FS8_SHADOW, // Linear layout, PCF
FORMAT_DF24S8,
FORMAT_DF16S8,
@@ -214,7 +233,8 @@
LOCK_READONLY,
LOCK_WRITEONLY,
LOCK_READWRITE,
- LOCK_DISCARD
+ LOCK_DISCARD,
+ LOCK_UPDATE // Write access which doesn't dirty the buffer, because it's being updated with the sibling's data.
};
class [[clang::lto_visibility_public]] Surface
@@ -222,7 +242,9 @@
private:
struct Buffer
{
- public:
+ friend Surface;
+
+ private:
void write(int x, int y, int z, const Color<float> &color);
void write(int x, int y, const Color<float> &color);
void write(void *element, const Color<float> &color);
@@ -230,7 +252,7 @@
Color<float> read(int x, int y) const;
Color<float> read(void *element) const;
Color<float> sample(float x, float y, float z) const;
- Color<float> sample(float x, float y) const;
+ Color<float> sample(float x, float y, int layer) const;
void *lockRect(int x, int y, int z, Lock lock);
void unlockRect();
@@ -239,24 +261,28 @@
int width;
int height;
int depth;
+ short border;
+ short samples;
+
int bytes;
int pitchB;
int pitchP;
int sliceB;
int sliceP;
- Format format;
- Lock lock;
- bool dirty;
+ Format format;
+ AtomicInt lock;
+
+ bool dirty; // Sibling internal/external buffer doesn't match.
};
protected:
Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
- Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
+ Surface(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0);
public:
static Surface *create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
- static Surface *create(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
+ static Surface *create(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0);
virtual ~Surface() = 0;
@@ -265,6 +291,7 @@
inline int getWidth() const;
inline int getHeight() const;
inline int getDepth() const;
+ inline int getBorder() const;
inline Format getFormat(bool internal = false) const;
inline int getPitchB(bool internal = false) const;
inline int getPitchP(bool internal = false) const;
@@ -296,6 +323,7 @@
void sync(); // Wait for lock(s) to be released.
inline bool isUnlocked() const; // Only reliable after sync().
+ inline int getSamples() const;
inline int getMultiSampleCount() const;
inline int getSuperSampleCount() const;
@@ -315,22 +343,26 @@
void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter);
void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter);
+ enum Edge { TOP, BOTTOM, RIGHT, LEFT };
+ void copyCubeEdge(Edge dstEdge, Surface *src, Edge srcEdge);
+ void computeCubeCorner(int x0, int y0, int x1, int y1);
+
bool hasStencil() const;
bool hasDepth() const;
bool hasPalette() const;
bool isRenderTarget() const;
- bool hasDirtyMipmaps() const;
- void cleanMipmaps();
+ bool hasDirtyContents() const;
+ void markContentsClean();
inline bool isExternalDirty() const;
Resource *getResource();
static int bytes(Format format);
- static int pitchB(int width, Format format, bool target);
- static int pitchP(int width, Format format, bool target);
- static int sliceB(int width, int height, Format format, bool target);
- static int sliceP(int width, int height, Format format, bool target);
- static unsigned int size(int width, int height, int depth, Format format); // FIXME: slice * depth
+ static int pitchB(int width, int border, Format format, bool target);
+ static int pitchP(int width, int border, Format format, bool target);
+ static int sliceB(int width, int height, int border, Format format, bool target);
+ static int sliceP(int width, int height, int border, Format format, bool target);
+ static unsigned int size(int width, int height, int depth, int border, int samples, Format format); // FIXME: slice * depth
static bool isStencil(Format format);
static bool isDepth(Format format);
@@ -341,6 +373,7 @@
static bool isUnsignedComponent(Format format, int component);
static bool isSRGBreadable(Format format);
static bool isSRGBwritable(Format format);
+ static bool isSRGBformat(Format format);
static bool isCompressed(Format format);
static bool isSignedNonNormalizedInteger(Format format);
static bool isUnsignedNonNormalizedInteger(Format format);
@@ -358,7 +391,6 @@
typedef unsigned int dword;
typedef uint64_t qword;
- #if S3TC_SUPPORT
struct DXT1
{
word c0;
@@ -392,7 +424,6 @@
word c1;
dword clut;
};
- #endif
struct ATI2
{
@@ -433,27 +464,25 @@
};
};
- static void decodeR8G8B8(Buffer &destination, const Buffer &source);
- static void decodeX1R5G5B5(Buffer &destination, const Buffer &source);
- static void decodeA1R5G5B5(Buffer &destination, const Buffer &source);
- static void decodeX4R4G4B4(Buffer &destination, const Buffer &source);
- static void decodeA4R4G4B4(Buffer &destination, const Buffer &source);
- static void decodeP8(Buffer &destination, const Buffer &source);
+ static void decodeR8G8B8(Buffer &destination, Buffer &source);
+ static void decodeX1R5G5B5(Buffer &destination, Buffer &source);
+ static void decodeA1R5G5B5(Buffer &destination, Buffer &source);
+ static void decodeX4R4G4B4(Buffer &destination, Buffer &source);
+ static void decodeA4R4G4B4(Buffer &destination, Buffer &source);
+ static void decodeP8(Buffer &destination, Buffer &source);
- #if S3TC_SUPPORT
- static void decodeDXT1(Buffer &internal, const Buffer &external);
- static void decodeDXT3(Buffer &internal, const Buffer &external);
- static void decodeDXT5(Buffer &internal, const Buffer &external);
- #endif
- static void decodeATI1(Buffer &internal, const Buffer &external);
- static void decodeATI2(Buffer &internal, const Buffer &external);
- static void decodeEAC(Buffer &internal, const Buffer &external, int nbChannels, bool isSigned);
- static void decodeETC2(Buffer &internal, const Buffer &external, int nbAlphaBits, bool isSRGB);
- static void decodeASTC(Buffer &internal, const Buffer &external, int xSize, int ySize, int zSize, bool isSRGB);
+ static void decodeDXT1(Buffer &internal, Buffer &external);
+ static void decodeDXT3(Buffer &internal, Buffer &external);
+ static void decodeDXT5(Buffer &internal, Buffer &external);
+ static void decodeATI1(Buffer &internal, Buffer &external);
+ static void decodeATI2(Buffer &internal, Buffer &external);
+ static void decodeEAC(Buffer &internal, Buffer &external, int nbChannels, bool isSigned);
+ static void decodeETC2(Buffer &internal, Buffer &external, int nbAlphaBits, bool isSRGB);
+ static void decodeASTC(Buffer &internal, Buffer &external, int xSize, int ySize, int zSize, bool isSRGB);
static void update(Buffer &destination, Buffer &source);
static void genericUpdate(Buffer &destination, Buffer &source);
- static void *allocateBuffer(int width, int height, int depth, Format format);
+ static void *allocateBuffer(int width, int height, int depth, int border, int samples, Format format);
static void memfill4(void *buffer, int pattern, int bytes);
bool identicalFormats() const;
@@ -468,7 +497,7 @@
const bool lockable;
const bool renderTarget;
- bool dirtyMipmaps;
+ bool dirtyContents; // Sibling surfaces need updating (mipmaps / cube borders).
unsigned int paletteUsed;
static unsigned int *palette; // FIXME: Not multi-device safe
@@ -509,6 +538,11 @@
return external.depth;
}
+ int Surface::getBorder() const
+ {
+ return internal.border;
+ }
+
Format Surface::getFormat(bool internal) const
{
return internal ? getInternalFormat() : getExternalFormat();
@@ -599,14 +633,19 @@
return stencil.sliceB;
}
+ int Surface::getSamples() const
+ {
+ return internal.samples;
+ }
+
int Surface::getMultiSampleCount() const
{
- return sw::min(internal.depth, 4);
+ return sw::min((int)internal.samples, 4);
}
int Surface::getSuperSampleCount() const
{
- return internal.depth > 4 ? internal.depth / 4 : 1;
+ return internal.samples > 4 ? internal.samples / 4 : 1;
}
bool Surface::isUnlocked() const
diff --git a/src/Renderer/TextureStage.cpp b/src/Renderer/TextureStage.cpp
index 583f82e..0327478 100644
--- a/src/Renderer/TextureStage.cpp
+++ b/src/Renderer/TextureStage.cpp
@@ -15,7 +15,7 @@
#include "TextureStage.hpp"
#include "Sampler.hpp"
-#include "Debug.hpp"
+#include "Common/Debug.hpp"
#include <string.h>
diff --git a/src/Renderer/Vector.cpp b/src/Renderer/Vector.cpp
index a212f3d..4a02534 100644
--- a/src/Renderer/Vector.cpp
+++ b/src/Renderer/Vector.cpp
@@ -14,8 +14,8 @@
#include "Vector.hpp"
-#include "Math.hpp"
#include "Matrix.hpp"
+#include "Common/Math.hpp"
namespace sw
{
diff --git a/src/Renderer/VertexProcessor.cpp b/src/Renderer/VertexProcessor.cpp
index 6972d94..cc9bd25 100644
--- a/src/Renderer/VertexProcessor.cpp
+++ b/src/Renderer/VertexProcessor.cpp
@@ -14,13 +14,13 @@
#include "VertexProcessor.hpp"
-#include "Math.hpp"
-#include "VertexPipeline.hpp"
-#include "VertexProgram.hpp"
-#include "VertexShader.hpp"
-#include "PixelShader.hpp"
-#include "Constants.hpp"
-#include "Debug.hpp"
+#include "Shader/VertexPipeline.hpp"
+#include "Shader/VertexProgram.hpp"
+#include "Shader/VertexShader.hpp"
+#include "Shader/PixelShader.hpp"
+#include "Shader/Constants.hpp"
+#include "Common/Math.hpp"
+#include "Common/Debug.hpp"
#include <string.h>
@@ -647,6 +647,15 @@
else ASSERT(false);
}
+ void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
+ {
+ if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
+ {
+ context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc);
+ }
+ else ASSERT(false);
+ }
+
void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
{
if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
@@ -916,7 +925,7 @@
state.shaderID = 0;
}
- state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
+ state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300;
state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
@@ -986,7 +995,7 @@
{
if(context->vertexShader->usesSampler(i))
{
- state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
+ state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
}
}
}
@@ -1001,7 +1010,7 @@
state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
}
}
- else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
+ else if(!context->preTransformed || context->pixelShaderModel() < 0x0300)
{
state.output[Pos].write = 0xF;
@@ -1059,7 +1068,7 @@
}
}
- if(context->vertexShaderVersion() < 0x0300)
+ if(context->vertexShaderModel() < 0x0300)
{
state.output[C0].clamp = 0xF;
state.output[C1].clamp = 0xF;
diff --git a/src/Renderer/VertexProcessor.hpp b/src/Renderer/VertexProcessor.hpp
index 3552f84..cd3849a 100644
--- a/src/Renderer/VertexProcessor.hpp
+++ b/src/Renderer/VertexProcessor.hpp
@@ -50,10 +50,10 @@
uint64_t shaderID;
- bool fixedFunction : 1;
- bool textureSampling : 1;
- unsigned int positionRegister : BITS(MAX_VERTEX_OUTPUTS);
- unsigned int pointSizeRegister : BITS(MAX_VERTEX_OUTPUTS);
+ bool fixedFunction : 1; // TODO: Eliminate by querying shader.
+ bool textureSampling : 1; // TODO: Eliminate by querying shader.
+ unsigned int positionRegister : BITS(MAX_VERTEX_OUTPUTS); // TODO: Eliminate by querying shader.
+ unsigned int pointSizeRegister : BITS(MAX_VERTEX_OUTPUTS); // TODO: Eliminate by querying shader.
unsigned int vertexBlendMatrixCount : 3;
bool indexedVertexBlendEnable : 1;
@@ -91,7 +91,7 @@
TextureState textureState[8];
- Sampler::State samplerState[VERTEX_TEXTURE_IMAGE_UNITS];
+ Sampler::State sampler[VERTEX_TEXTURE_IMAGE_UNITS];
struct Input
{
@@ -263,6 +263,7 @@
void setSwizzleG(unsigned int sampler, SwizzleType swizzleG);
void setSwizzleB(unsigned int sampler, SwizzleType swizzleB);
void setSwizzleA(unsigned int sampler, SwizzleType swizzleA);
+ void setCompareFunc(unsigned int sampler, CompareFunc compare);
void setBaseLevel(unsigned int sampler, int baseLevel);
void setMaxLevel(unsigned int sampler, int maxLevel);
void setMinLod(unsigned int sampler, float minLod);
diff --git a/src/Shader/BUILD.gn b/src/Shader/BUILD.gn
index 3b19766..baf1233 100644
--- a/src/Shader/BUILD.gn
+++ b/src/Shader/BUILD.gn
@@ -55,8 +55,5 @@
include_dirs = [
".",
"..",
- "../Common",
- "../Main",
- "../Renderer",
]
}
diff --git a/src/Shader/Constants.cpp b/src/Shader/Constants.cpp
index e02ba03..06dda32 100644
--- a/src/Shader/Constants.cpp
+++ b/src/Shader/Constants.cpp
@@ -264,17 +264,17 @@
for(int i = 0; i < 256; i++)
{
- sRGBtoLinear8_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0xFF) * 0x1000 + 0.5f);
+ sRGBtoLinear8_16[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0xFF) * 0xFFFF + 0.5f);
}
for(int i = 0; i < 64; i++)
{
- sRGBtoLinear6_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x3F) * 0x1000 + 0.5f);
+ sRGBtoLinear6_16[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x3F) * 0xFFFF + 0.5f);
}
for(int i = 0; i < 32; i++)
{
- sRGBtoLinear5_12[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x1F) * 0x1000 + 0.5f);
+ sRGBtoLinear5_16[i] = (unsigned short)(sw::sRGBtoLinear((float)i / 0x1F) * 0xFFFF + 0.5f);
}
for(int i = 0; i < 0x1000; i++)
diff --git a/src/Shader/Constants.hpp b/src/Shader/Constants.hpp
index 5210643..6b70e04 100644
--- a/src/Shader/Constants.hpp
+++ b/src/Shader/Constants.hpp
@@ -22,7 +22,7 @@
struct Constants
{
Constants();
-
+
unsigned int transposeBit0[16];
unsigned int transposeBit1[16];
unsigned int transposeBit2[16];
@@ -67,9 +67,9 @@
dword4 maskD01X[4];
word4 mask565Q[8];
- unsigned short sRGBtoLinear8_12[256];
- unsigned short sRGBtoLinear6_12[64];
- unsigned short sRGBtoLinear5_12[32];
+ unsigned short sRGBtoLinear8_16[256];
+ unsigned short sRGBtoLinear6_16[64];
+ unsigned short sRGBtoLinear5_16[32];
unsigned short linearToSRGB12_16[4096];
unsigned short sRGBtoLinear12_16[4096];
diff --git a/src/Shader/PixelPipeline.cpp b/src/Shader/PixelPipeline.cpp
index 66d6a09..d4faebd 100644
--- a/src/Shader/PixelPipeline.cpp
+++ b/src/Shader/PixelPipeline.cpp
@@ -13,8 +13,8 @@
// limitations under the License.
#include "PixelPipeline.hpp"
-#include "Renderer.hpp"
#include "SamplerCore.hpp"
+#include "Renderer/Renderer.hpp"
namespace sw
{
@@ -49,7 +49,7 @@
if(state.textureStage[stage].usesTexture)
{
- sampleTexture(texture, stage, stage);
+ texture = sampleTexture(stage, stage);
}
blendTexture(temp, texture, stage);
@@ -88,7 +88,7 @@
const Src &src1 = instruction->src[1];
const Src &src2 = instruction->src[2];
- unsigned short version = shader->getVersion();
+ unsigned short shaderModel = shader->getShaderModel();
bool pairing = i + 1 < shader->getLength() && shader->getInstruction(i + 1)->coissue; // First instruction of pair
bool coissue = instruction->coissue; // Second instruction of pair
@@ -101,10 +101,10 @@
if(src1.type != Shader::PARAMETER_VOID) s1 = fetchRegister(src1);
if(src2.type != Shader::PARAMETER_VOID) s2 = fetchRegister(src2);
- Float4 x = version < 0x0104 ? v[2 + dst.index].x : v[2 + src0.index].x;
- Float4 y = version < 0x0104 ? v[2 + dst.index].y : v[2 + src0.index].y;
- Float4 z = version < 0x0104 ? v[2 + dst.index].z : v[2 + src0.index].z;
- Float4 w = version < 0x0104 ? v[2 + dst.index].w : v[2 + src0.index].w;
+ Float4 x = shaderModel < 0x0104 ? v[2 + dst.index].x : v[2 + src0.index].x;
+ Float4 y = shaderModel < 0x0104 ? v[2 + dst.index].y : v[2 + src0.index].y;
+ Float4 z = shaderModel < 0x0104 ? v[2 + dst.index].z : v[2 + src0.index].z;
+ Float4 w = shaderModel < 0x0104 ? v[2 + dst.index].w : v[2 + src0.index].w;
switch(opcode)
{
@@ -126,7 +126,7 @@
case Shader::OPCODE_DP4: DP4(d, s0, s1); break;
case Shader::OPCODE_LRP: LRP(d, s0, s1, s2); break;
case Shader::OPCODE_TEXCOORD:
- if(version < 0x0104)
+ if(shaderModel < 0x0104)
{
TEXCOORD(d, x, y, z, dst.index);
}
@@ -143,11 +143,11 @@
}
break;
case Shader::OPCODE_TEXKILL:
- if(version < 0x0104)
+ if(shaderModel < 0x0104)
{
TEXKILL(cMask, x, y, z);
}
- else if(version == 0x0104)
+ else if(shaderModel == 0x0104)
{
if(dst.type == Shader::PARAMETER_TEXTURE)
{
@@ -161,11 +161,11 @@
else ASSERT(false);
break;
case Shader::OPCODE_TEX:
- if(version < 0x0104)
+ if(shaderModel < 0x0104)
{
TEX(d, x, y, z, dst.index, false);
}
- else if(version == 0x0104)
+ else if(shaderModel == 0x0104)
{
if(src0.type == Shader::PARAMETER_TEXTURE)
{
@@ -256,15 +256,15 @@
}
}
}
- }
- Bool PixelPipeline::alphaTest(Int cMask[4])
- {
current.x = Min(current.x, Short4(0x0FFF)); current.x = Max(current.x, Short4(0x0000));
current.y = Min(current.y, Short4(0x0FFF)); current.y = Max(current.y, Short4(0x0000));
current.z = Min(current.z, Short4(0x0FFF)); current.z = Max(current.z, Short4(0x0000));
current.w = Min(current.w, Short4(0x0FFF)); current.w = Max(current.w, Short4(0x0000));
+ }
+ Bool PixelPipeline::alphaTest(Int cMask[4])
+ {
if(!state.alphaTestActive())
{
return true;
@@ -356,6 +356,7 @@
case FORMAT_G32R32F:
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ // case FORMAT_X32B32G32R32F_UNSIGNED: // Not renderable in any fixed-function API.
convertSigned12(oC, current);
PixelRoutine::fogBlend(oC, fog);
@@ -1207,7 +1208,7 @@
current.z = AddSat(current.z, specular.z);
}
- void PixelPipeline::sampleTexture(Vector4s &c, int coordinates, int stage, bool project)
+ Vector4s PixelPipeline::sampleTexture(int coordinates, int stage, bool project)
{
Float4 x = v[2 + coordinates].x;
Float4 y = v[2 + coordinates].y;
@@ -1222,11 +1223,13 @@
perturbate = false;
}
- sampleTexture(c, stage, x, y, z, w, project);
+ return sampleTexture(stage, x, y, z, w, project);
}
- void PixelPipeline::sampleTexture(Vector4s &c, int stage, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project)
+ Vector4s PixelPipeline::sampleTexture(int stage, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project)
{
+ Vector4s c;
+
#if PERF_PROFILE
Long texTime = Ticks();
#endif
@@ -1238,7 +1241,7 @@
if(!project)
{
- sampler[stage]->sampleTexture(texture, c, u, v, w, q, dsx, dsy);
+ c = SamplerCore(constants, state.sampler[stage]).sampleTexture(texture, u, v, w, q, q, dsx, dsy);
}
else
{
@@ -1248,12 +1251,14 @@
Float4 v_q = v * rq;
Float4 w_q = w * rq;
- sampler[stage]->sampleTexture(texture, c, u_q, v_q, w_q, q, dsx, dsy);
+ c = SamplerCore(constants, state.sampler[stage]).sampleTexture(texture, u_q, v_q, w_q, q, q, dsx, dsy);
}
#if PERF_PROFILE
cycles[PERF_TEX] += Ticks() - texTime;
#endif
+
+ return c;
}
Short4 PixelPipeline::convertFixed12(RValue<Float4> cf)
@@ -1470,22 +1475,18 @@
{
// FIXME: Long fixed-point multiply fixup
{ dst.x = MulHigh(src0.x, src1.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, src2.x); }
- {
- dst.y = MulHigh(src0.y, src1.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, src2.y);
- }
- {dst.z = MulHigh(src0.z, src1.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, src2.z); }
- {dst.w = MulHigh(src0.w, src1.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, src2.w); }
+ { dst.y = MulHigh(src0.y, src1.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, src2.y); }
+ { dst.z = MulHigh(src0.z, src1.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, src2.z); }
+ { dst.w = MulHigh(src0.w, src1.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, src2.w); }
}
void PixelPipeline::MUL(Vector4s &dst, Vector4s &src0, Vector4s &src1)
{
// FIXME: Long fixed-point multiply fixup
{ dst.x = MulHigh(src0.x, src1.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); dst.x = AddSat(dst.x, dst.x); }
- {
- dst.y = MulHigh(src0.y, src1.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y);
- }
- {dst.z = MulHigh(src0.z, src1.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); }
- {dst.w = MulHigh(src0.w, src1.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); }
+ { dst.y = MulHigh(src0.y, src1.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); dst.y = AddSat(dst.y, dst.y); }
+ { dst.z = MulHigh(src0.z, src1.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); dst.z = AddSat(dst.z, dst.z); }
+ { dst.w = MulHigh(src0.w, src1.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); dst.w = AddSat(dst.w, dst.w); }
}
void PixelPipeline::DP3(Vector4s &dst, Vector4s &src0, Vector4s &src1)
@@ -1647,7 +1648,7 @@
v_ = Float4(0.0f);
w_ = Float4(0.0f);
- sampleTexture(dst, stage, u_, v_, w_, w_);
+ dst = sampleTexture(stage, u_, v_, w_, w_);
}
void PixelPipeline::TEXKILL(Int cMask[4], Float4 &u, Float4 &v, Float4 &s)
@@ -1665,7 +1666,7 @@
void PixelPipeline::TEXKILL(Int cMask[4], Vector4s &src)
{
Short4 test = src.x | src.y | src.z;
- Int kill = SignMask(Pack(test, test)) ^ 0x0000000F;
+ Int kill = SignMask(PackSigned(test, test)) ^ 0x0000000F;
for(unsigned int q = 0; q < state.multiSample; q++)
{
@@ -1675,7 +1676,7 @@
void PixelPipeline::TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int sampler, bool project)
{
- sampleTexture(dst, sampler, u, v, s, s, project);
+ dst = sampleTexture(sampler, u, v, s, s, project);
}
void PixelPipeline::TEXLD(Vector4s &dst, Vector4s &src, int sampler, bool project)
@@ -1684,7 +1685,7 @@
Float4 v = Float4(src.y) * Float4(1.0f / 0x0FFE);
Float4 s = Float4(src.z) * Float4(1.0f / 0x0FFE);
- sampleTexture(dst, sampler, u, v, s, s, project);
+ dst = sampleTexture(sampler, u, v, s, s, project);
}
void PixelPipeline::TEXBEM(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage)
@@ -1705,7 +1706,7 @@
Float4 u_ = u + du;
Float4 v_ = v + dv;
- sampleTexture(dst, stage, u_, v_, s, s);
+ dst = sampleTexture(stage, u_, v_, s, s);
}
void PixelPipeline::TEXBEML(Vector4s &dst, Vector4s &src, Float4 &u, Float4 &v, Float4 &s, int stage)
@@ -1726,7 +1727,7 @@
Float4 u_ = u + du;
Float4 v_ = v + dv;
- sampleTexture(dst, stage, u_, v_, s, s);
+ dst = sampleTexture(stage, u_, v_, s, s);
Short4 L;
@@ -1748,7 +1749,7 @@
Float4 v = Float4(src0.x) * Float4(1.0f / 0x0FFE);
Float4 s = Float4(src0.z) * Float4(1.0f / 0x0FFE);
- sampleTexture(dst, stage, u, v, s, s);
+ dst = sampleTexture(stage, u, v, s, s);
}
void PixelPipeline::TEXREG2GB(Vector4s &dst, Vector4s &src0, int stage)
@@ -1757,7 +1758,7 @@
Float4 v = Float4(src0.z) * Float4(1.0f / 0x0FFE);
Float4 s = v;
- sampleTexture(dst, stage, u, v, s, s);
+ dst = sampleTexture(stage, u, v, s, s);
}
void PixelPipeline::TEXREG2RGB(Vector4s &dst, Vector4s &src0, int stage)
@@ -1766,7 +1767,7 @@
Float4 v = Float4(src0.y) * Float4(1.0f / 0x0FFE);
Float4 s = Float4(src0.z) * Float4(1.0f / 0x0FFE);
- sampleTexture(dst, stage, u, v, s, s);
+ dst = sampleTexture(stage, u, v, s, s);
}
void PixelPipeline::TEXM3X2DEPTH(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src, bool signedScaling)
@@ -1790,7 +1791,7 @@
w_ = Float4(0.0f);
- sampleTexture(dst, stage, u_, v_, w_, w_);
+ dst = sampleTexture(stage, u_, v_, w_, w_);
}
void PixelPipeline::TEXM3X3(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, Vector4s &src0, bool signedScaling)
@@ -1861,14 +1862,14 @@
v__ -= E[1] * u_;
w__ -= E[2] * u_;
- sampleTexture(dst, stage, u__, v__, w__, w__);
+ dst = sampleTexture(stage, u__, v__, w__, w__);
}
void PixelPipeline::TEXM3X3TEX(Vector4s &dst, Float4 &u, Float4 &v, Float4 &s, int stage, Vector4s &src0, bool signedScaling)
{
TEXM3X3PAD(u, v, s, src0, 2, signedScaling);
- sampleTexture(dst, stage, u_, v_, w_, w_);
+ dst = sampleTexture(stage, u_, v_, w_, w_);
}
void PixelPipeline::TEXM3X3VSPEC(Vector4s &dst, Float4 &x, Float4 &y, Float4 &z, int stage, Vector4s &src0)
@@ -1905,7 +1906,7 @@
v__ -= E[1] * u_;
w__ -= E[2] * u_;
- sampleTexture(dst, stage, u__, v__, w__, w__);
+ dst = sampleTexture(stage, u__, v__, w__, w__);
}
void PixelPipeline::TEXDEPTH()
diff --git a/src/Shader/PixelPipeline.hpp b/src/Shader/PixelPipeline.hpp
index d8d2a03..66f0ec7 100644
--- a/src/Shader/PixelPipeline.hpp
+++ b/src/Shader/PixelPipeline.hpp
@@ -59,8 +59,8 @@
void fogBlend(Vector4s ¤t, Float4 &fog);
void specularPixel(Vector4s ¤t, Vector4s &specular);
- void sampleTexture(Vector4s &c, int coordinates, int sampler, bool project = false);
- void sampleTexture(Vector4s &c, int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project = false);
+ Vector4s sampleTexture(int coordinates, int sampler, bool project = false);
+ Vector4s sampleTexture(int sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, bool project = false);
Short4 convertFixed12(RValue<Float4> cf);
void convertFixed12(Vector4s &cs, Vector4f &cf);
diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp
index 948f103..0f0f6bd 100644
--- a/src/Shader/PixelProgram.cpp
+++ b/src/Shader/PixelProgram.cpp
@@ -13,9 +13,10 @@
// limitations under the License.
#include "PixelProgram.hpp"
-#include "Primitive.hpp"
-#include "Renderer.hpp"
+
#include "SamplerCore.hpp"
+#include "Renderer/Primitive.hpp"
+#include "Renderer/Renderer.hpp"
namespace sw
{
@@ -26,7 +27,7 @@
void PixelProgram::setBuiltins(Int &x, Int &y, Float4(&z)[4], Float4 &w)
{
- if(shader->getVersion() >= 0x0300)
+ if(shader->getShaderModel() >= 0x0300)
{
if(shader->isVPosDeclared())
{
@@ -229,6 +230,8 @@
case Shader::OPCODE_LRP: lrp(d, s0, s1, s2); break;
case Shader::OPCODE_STEP: step(d, s0, s1); break;
case Shader::OPCODE_SMOOTH: smooth(d, s0, s1, s2); break;
+ case Shader::OPCODE_ISINF: isinf(d, s0); break;
+ case Shader::OPCODE_ISNAN: isnan(d, s0); break;
case Shader::OPCODE_FLOATBITSTOINT:
case Shader::OPCODE_FLOATBITSTOUINT:
case Shader::OPCODE_INTBITSTOFLOAT:
@@ -280,17 +283,20 @@
case Shader::OPCODE_M3X4: M3X4(d, s0, src1); break;
case Shader::OPCODE_M3X3: M3X3(d, s0, src1); break;
case Shader::OPCODE_M3X2: M3X2(d, s0, src1); break;
- case Shader::OPCODE_TEX: TEXLD(d, s0, src1, project, bias); break;
- case Shader::OPCODE_TEXLDD: TEXLDD(d, s0, src1, s2, s3); break;
- case Shader::OPCODE_TEXLDL: TEXLDL(d, s0, src1); break;
+ case Shader::OPCODE_TEX: TEX(d, s0, src1, project, bias); break;
+ case Shader::OPCODE_TEXLDD: TEXGRAD(d, s0, src1, s2, s3); break;
+ case Shader::OPCODE_TEXLDL: TEXLOD(d, s0, src1, s0.w); break;
+ case Shader::OPCODE_TEXLOD: TEXLOD(d, s0, src1, s2.x); break;
case Shader::OPCODE_TEXSIZE: TEXSIZE(d, s0.x, src1); break;
case Shader::OPCODE_TEXKILL: TEXKILL(cMask, d, dst.mask); break;
- case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2, bias); break;
- case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(d, s0, src1, s2, bias); break;
- case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1); break;
- case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(d, s0, src1, s2); break;
+ case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2); break;
+ case Shader::OPCODE_TEXLODOFFSET: TEXLODOFFSET(d, s0, src1, s2, s3.x); break;
+ case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2.x); break;
+ case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCHOFFSET(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_TEXGRAD: TEXGRAD(d, s0, src1, s2, s3); break;
- case Shader::OPCODE_TEXGRADOFFSET: TEXGRAD(d, s0, src1, s2, s3, s4); break;
+ case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4); break;
+ case Shader::OPCODE_TEXBIAS: TEXBIAS(d, s0, src1, s2.x); break;
+ case Shader::OPCODE_TEXOFFSETBIAS: TEXOFFSETBIAS(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_DISCARD: DISCARD(cMask, instruction); break;
case Shader::OPCODE_DFDX: DFDX(d, s0); break;
case Shader::OPCODE_DFDY: DFDY(d, s0); break;
@@ -333,21 +339,6 @@
if(dst.type != Shader::PARAMETER_VOID && dst.type != Shader::PARAMETER_LABEL && opcode != Shader::OPCODE_TEXKILL && opcode != Shader::OPCODE_NOP)
{
- if(dst.integer)
- {
- switch(opcode)
- {
- case Shader::OPCODE_DIV:
- if(dst.x) d.x = Trunc(d.x);
- if(dst.y) d.y = Trunc(d.y);
- if(dst.z) d.z = Trunc(d.z);
- if(dst.w) d.w = Trunc(d.w);
- break;
- default:
- break; // No truncation to integer required when arguments are integer
- }
- }
-
if(dst.saturate)
{
if(dst.x) d.x = Max(d.x, Float4(0.0f));
@@ -534,12 +525,17 @@
c[i] = oC[i];
}
}
+
+ clampColor(c);
+
+ if(state.depthOverride)
+ {
+ oDepth = Min(Max(oDepth, Float4(0.0f)), Float4(1.0f));
+ }
}
Bool PixelProgram::alphaTest(Int cMask[4])
{
- clampColor(c);
-
if(!state.alphaTestActive())
{
return true;
@@ -641,6 +637,7 @@
case FORMAT_G32R32F:
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_R32I:
case FORMAT_G32R32I:
case FORMAT_A32B32G32R32I:
@@ -677,13 +674,13 @@
}
}
- void PixelProgram::sampleTexture(Vector4f &c, const Src &sampler, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
+ Vector4f PixelProgram::sampleTexture(const Src &sampler, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{
Vector4f tmp;
if(sampler.type == Shader::PARAMETER_SAMPLER && sampler.rel.type == Shader::PARAMETER_VOID)
{
- sampleTexture(tmp, sampler.index, uvwq, dsx, dsy, offset, function);
+ tmp = sampleTexture(sampler.index, uvwq, bias, dsx, dsy, offset, function);
}
else
{
@@ -695,31 +692,36 @@
{
If(index == i)
{
- sampleTexture(tmp, i, uvwq, dsx, dsy, offset, function);
+ tmp = sampleTexture(i, uvwq, bias, dsx, dsy, offset, function);
// FIXME: When the sampler states are the same, we could use one sampler and just index the texture
}
}
}
}
+ Vector4f c;
c.x = tmp[(sampler.swizzle >> 0) & 0x3];
c.y = tmp[(sampler.swizzle >> 2) & 0x3];
c.z = tmp[(sampler.swizzle >> 4) & 0x3];
c.w = tmp[(sampler.swizzle >> 6) & 0x3];
+
+ return c;
}
- void PixelProgram::sampleTexture(Vector4f &c, int samplerIndex, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
+ Vector4f PixelProgram::sampleTexture(int samplerIndex, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{
#if PERF_PROFILE
Long texTime = Ticks();
#endif
Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + samplerIndex * sizeof(Texture);
- sampler[samplerIndex]->sampleTexture(texture, c, uvwq.x, uvwq.y, uvwq.z, uvwq.w, dsx, dsy, offset, function);
+ Vector4f c = SamplerCore(constants, state.sampler[samplerIndex]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, bias, dsx, dsy, offset, function);
#if PERF_PROFILE
cycles[PERF_TEX] += Ticks() - texTime;
#endif
+
+ return c;
}
void PixelProgram::clampColor(Vector4f oC[RENDERTARGETS])
@@ -775,6 +777,12 @@
case FORMAT_G8R8UI:
case FORMAT_A8B8G8R8UI:
break;
+ case FORMAT_X32B32G32R32F_UNSIGNED:
+ oC[index].x = Max(oC[index].x, Float4(0.0f));
+ oC[index].y = Max(oC[index].y, Float4(0.0f));
+ oC[index].z = Max(oC[index].z, Float4(0.0f));
+ oC[index].w = Max(oC[index].w, Float4(0.0f));
+ break;
default:
ASSERT(false);
}
@@ -1107,7 +1115,7 @@
dst.w = dot4(src0, row3);
}
- void PixelProgram::TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias)
+ void PixelProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias)
{
if(project)
{
@@ -1117,58 +1125,63 @@
proj.y = src0.y * rw;
proj.z = src0.z * rw;
- sampleTexture(dst, src1, proj, src0, src0, src0, Implicit);
+ dst = sampleTexture(src1, proj, src0.x, (src0), (src0), (src0), Implicit);
}
else
{
- sampleTexture(dst, src1, src0, src0, src0, src0, bias ? Bias : Implicit);
+ dst = sampleTexture(src1, src0, src0.x, (src0), (src0), (src0), bias ? Bias : Implicit);
}
}
- void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias)
+ void PixelProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset)
{
- sampleTexture(dst, src1, src0, src0, src0, src2, {bias ? Bias : Implicit, Offset});
+ dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), offset, {Implicit, Offset});
}
- void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, bool bias)
+ void PixelProgram::TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &lod)
{
- sampleTexture(dst, src1, src0, src0, src0, offset, {Lod, Offset});
+ dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Lod, Offset});
}
- void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1)
+ void PixelProgram::TEXBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &bias)
{
- sampleTexture(dst, src1, src0, src0, src0, src0, Fetch);
+ dst = sampleTexture(src1, src0, bias, (src0), (src0), (src0), Bias);
}
- void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset)
+ void PixelProgram::TEXOFFSETBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &bias)
{
- sampleTexture(dst, src1, src0, src0, src0, offset, {Fetch, Offset});
+ dst = sampleTexture(src1, src0, bias, (src0), (src0), offset, {Bias, Offset});
}
- void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3)
+ void PixelProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
{
- sampleTexture(dst, src1, src0, src2, src3, src0, Grad);
+ dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Fetch);
}
- void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset)
+ void PixelProgram::TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
{
- sampleTexture(dst, src1, src0, src2, src3, offset, {Grad, Offset});
+ dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Fetch, Offset});
}
- void PixelProgram::TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3)
+ void PixelProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy)
{
- sampleTexture(dst, src1, src0, src2, src3, src0, Grad);
+ dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, (src0), Grad);
}
- void PixelProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1)
+ void PixelProgram::TEXGRADOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy, Vector4f &offset)
{
- sampleTexture(dst, src1, src0, src0, src0, src0, Lod);
+ dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, offset, {Grad, Offset});
+ }
+
+ void PixelProgram::TEXLOD(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &lod)
+ {
+ dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Lod);
}
void PixelProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
{
Pointer<Byte> texture = data + OFFSET(DrawData, mipmap) + src1.index * sizeof(Texture);
- sampler[src1.index]->textureSize(texture, dst, lod);
+ dst = SamplerCore::textureSize(texture, lod);
}
void PixelProgram::TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask)
@@ -1238,25 +1251,7 @@
void PixelProgram::BREAK()
{
- BasicBlock *deadBlock = Nucleus::createBasicBlock();
- BasicBlock *endBlock = loopRepEndBlock[loopRepDepth - 1];
-
- if(breakDepth == 0)
- {
- enableIndex = enableIndex - breakDepth;
- Nucleus::createBr(endBlock);
- }
- else
- {
- enableBreak = enableBreak & ~enableStack[enableIndex];
- Bool allBreak = SignMask(enableBreak) == 0x0;
-
- enableIndex = enableIndex - breakDepth;
- branch(allBreak, endBlock, deadBlock);
- }
-
- Nucleus::setInsertBlock(deadBlock);
- enableIndex = enableIndex + breakDepth;
+ enableBreak = enableBreak & ~enableStack[enableIndex];
}
void PixelProgram::BREAKC(Vector4f &src0, Vector4f &src1, Control control)
@@ -1294,17 +1289,7 @@
{
condition &= enableStack[enableIndex];
- BasicBlock *continueBlock = Nucleus::createBasicBlock();
- BasicBlock *endBlock = loopRepEndBlock[loopRepDepth - 1];
-
enableBreak = enableBreak & ~condition;
- Bool allBreak = SignMask(enableBreak) == 0x0;
-
- enableIndex = enableIndex - breakDepth;
- branch(allBreak, endBlock, continueBlock);
-
- Nucleus::setInsertBlock(continueBlock);
- enableIndex = enableIndex + breakDepth;
}
void PixelProgram::CONTINUE()
@@ -1448,7 +1433,6 @@
if(isConditionalIf[ifDepth])
{
- breakDepth--;
enableIndex--;
}
}
@@ -1494,7 +1478,6 @@
Nucleus::setInsertBlock(endBlock);
enableIndex--;
- enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
whileTest = false;
}
@@ -1504,11 +1487,8 @@
BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
- Nucleus::createBr(loopRepEndBlock[loopRepDepth]);
+ Nucleus::createBr(endBlock);
Nucleus::setInsertBlock(endBlock);
-
- enableIndex--;
- enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
void PixelProgram::IF(const Src &src)
@@ -1599,7 +1579,6 @@
ifFalseBlock[ifDepth] = falseBlock;
ifDepth++;
- breakDepth++;
}
void PixelProgram::LABEL(int labelIndex)
@@ -1643,7 +1622,6 @@
iteration[loopDepth] = iteration[loopDepth] - 1; // FIXME: --
loopRepDepth++;
- breakDepth = 0;
}
void PixelProgram::REP(const Src &integerRegister)
@@ -1670,7 +1648,6 @@
iteration[loopDepth] = iteration[loopDepth] - 1; // FIXME: --
loopRepDepth++;
- breakDepth = 0;
}
void PixelProgram::WHILE(const Src &temporaryRegister)
@@ -1687,7 +1664,7 @@
Int4 restoreBreak = enableBreak;
Int4 restoreContinue = enableContinue;
- // FIXME: jump(testBlock)
+ // TODO: jump(testBlock)
Nucleus::createBr(testBlock);
Nucleus::setInsertBlock(testBlock);
enableContinue = restoreContinue;
@@ -1696,6 +1673,7 @@
Int4 condition = As<Int4>(src.x);
condition &= enableStack[enableIndex - 1];
if(shader->containsLeaveInstruction()) condition &= enableLeave;
+ if(shader->containsBreakInstruction()) condition &= enableBreak;
enableStack[enableIndex] = condition;
Bool notAllFalse = SignMask(condition) != 0;
@@ -1707,21 +1685,25 @@
Nucleus::setInsertBlock(loopBlock);
loopRepDepth++;
- breakDepth = 0;
}
void PixelProgram::SWITCH()
{
- enableIndex++;
- enableStack[enableIndex] = Int4(0xFFFFFFFF);
-
BasicBlock *endBlock = Nucleus::createBasicBlock();
loopRepTestBlock[loopRepDepth] = nullptr;
loopRepEndBlock[loopRepDepth] = endBlock;
+ Int4 restoreBreak = enableBreak;
+
+ BasicBlock *currentBlock = Nucleus::getInsertBlock();
+
+ Nucleus::setInsertBlock(endBlock);
+ enableBreak = restoreBreak;
+
+ Nucleus::setInsertBlock(currentBlock);
+
loopRepDepth++;
- breakDepth = 0;
}
void PixelProgram::RET()
diff --git a/src/Shader/PixelProgram.hpp b/src/Shader/PixelProgram.hpp
index b15177a..951e147 100644
--- a/src/Shader/PixelProgram.hpp
+++ b/src/Shader/PixelProgram.hpp
@@ -24,8 +24,8 @@
{
public:
PixelProgram(const PixelProcessor::State &state, const PixelShader *shader) :
- PixelRoutine(state, shader), r(shader && shader->dynamicallyIndexedTemporaries),
- loopDepth(-1), ifDepth(0), loopRepDepth(0), breakDepth(0), currentLabel(-1), whileTest(false)
+ PixelRoutine(state, shader), r(shader->dynamicallyIndexedTemporaries),
+ loopDepth(-1), ifDepth(0), loopRepDepth(0), currentLabel(-1), whileTest(false)
{
for(int i = 0; i < 2048; ++i)
{
@@ -34,12 +34,12 @@
enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
- if(shader && shader->containsBreakInstruction())
+ if(shader->containsBreakInstruction())
{
enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
- if(shader && shader->containsContinueInstruction())
+ if(shader->containsContinueInstruction())
{
enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
@@ -82,8 +82,8 @@
Int4 enableContinue;
Int4 enableLeave;
- void sampleTexture(Vector4f &c, const Src &sampler, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
- void sampleTexture(Vector4f &c, int samplerIndex, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
+ Vector4f sampleTexture(const Src &sampler, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
+ Vector4f sampleTexture(int samplerIndex, Vector4f &uvwq, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
// Raster operations
void clampColor(Vector4f oC[RENDERTARGETS]);
@@ -106,17 +106,18 @@
void M3X4(Vector4f &dst, Vector4f &src0, const Src &src1);
void M4X3(Vector4f &dst, Vector4f &src0, const Src &src1);
void M4X4(Vector4f &dst, Vector4f &src0, const Src &src1);
- void TEXLD(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
- void TEXLDD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, Vector4f &src3);
- void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1);
+ void TEX(Vector4f &dst, Vector4f &src0, const Src &src1, bool project, bool bias);
+ void TEXLOD(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &lod);
+ void TEXBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Float4 &bias);
void TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1);
void TEXKILL(Int cMask[4], Vector4f &src, unsigned char mask);
- void TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias);
- void TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &src2, bool bias);
- void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&);
- void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
- void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
- void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4);
+ void TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset);
+ void TEXOFFSETBIAS(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &bias);
+ void TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &offset, Float4 &lod);
+ void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src &, Float4 &lod);
+ void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &offset, Float4 &lod);
+ void TEXGRAD(Vector4f &dst, Vector4f &src0, const Src &src1, Vector4f &dsx, Vector4f &dsy);
+ void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src &, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
void DISCARD(Int cMask[4], const Shader::Instruction *instruction);
void DFDX(Vector4f &dst, Vector4f &src);
void DFDY(Vector4f &dst, Vector4f &src);
@@ -152,7 +153,6 @@
int ifDepth;
int loopRepDepth;
- int breakDepth;
int currentLabel;
bool whileTest;
diff --git a/src/Shader/PixelRoutine.cpp b/src/Shader/PixelRoutine.cpp
index 44fafd3..1c300b0 100644
--- a/src/Shader/PixelRoutine.cpp
+++ b/src/Shader/PixelRoutine.cpp
@@ -14,13 +14,13 @@
#include "PixelRoutine.hpp"
-#include "Renderer.hpp"
-#include "QuadRasterizer.hpp"
-#include "Surface.hpp"
-#include "Primitive.hpp"
#include "SamplerCore.hpp"
#include "Constants.hpp"
-#include "Debug.hpp"
+#include "Renderer/Renderer.hpp"
+#include "Renderer/QuadRasterizer.hpp"
+#include "Renderer/Surface.hpp"
+#include "Renderer/Primitive.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
@@ -31,7 +31,7 @@
PixelRoutine::PixelRoutine(const PixelProcessor::State &state, const PixelShader *shader) : QuadRasterizer(state, shader), v(shader && shader->dynamicallyIndexedInput)
{
- if(!shader || shader->getVersion() < 0x0200 || forceClearRegisters)
+ if(!shader || shader->getShaderModel() < 0x0200 || forceClearRegisters)
{
for(int i = 0; i < MAX_FRAGMENT_INPUTS; i++)
{
@@ -45,10 +45,6 @@
PixelRoutine::~PixelRoutine()
{
- for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
- {
- delete sampler[i];
- }
}
void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y)
@@ -57,11 +53,6 @@
Long pipeTime = Ticks();
#endif
- for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
- {
- sampler[i] = new SamplerCore(constants, state.sampler[i]);
- }
-
const bool earlyDepthTest = !state.depthOverride && !state.alphaTestActive();
Int zMask[4]; // Depth mask
@@ -94,7 +85,7 @@
x -= *Pointer<Float4>(constants + OFFSET(Constants,X) + q * sizeof(float4));
}
- z[q] = interpolate(x, Dz[q], z[q], primitive + OFFSET(Primitive,z), false, false);
+ z[q] = interpolate(x, Dz[q], z[q], primitive + OFFSET(Primitive,z), false, false, state.depthClamp);
}
}
@@ -141,7 +132,7 @@
if(interpolateW())
{
- w = interpolate(xxxx, Dw, rhw, primitive + OFFSET(Primitive,w), false, false);
+ w = interpolate(xxxx, Dw, rhw, primitive + OFFSET(Primitive,w), false, false, false);
rhw = reciprocal(w, false, false, true);
if(state.centroid)
@@ -158,7 +149,7 @@
{
if(!state.interpolant[interpolant].centroid)
{
- v[interpolant][component] = interpolate(xxxx, Dv[interpolant][component], rhw, primitive + OFFSET(Primitive, V[interpolant][component]), (state.interpolant[interpolant].flat & (1 << component)) != 0, state.perspective);
+ v[interpolant][component] = interpolate(xxxx, Dv[interpolant][component], rhw, primitive + OFFSET(Primitive, V[interpolant][component]), (state.interpolant[interpolant].flat & (1 << component)) != 0, state.perspective, false);
}
else
{
@@ -193,7 +184,7 @@
if(state.fog.component)
{
- f = interpolate(xxxx, Df, rhw, primitive + OFFSET(Primitive,f), state.fog.flat & 0x01, state.perspective);
+ f = interpolate(xxxx, Df, rhw, primitive + OFFSET(Primitive,f), state.fog.flat & 0x01, state.perspective, false);
}
setBuiltins(x, y, z, w);
@@ -544,29 +535,29 @@
break;
case ALPHA_EQUAL:
cmp = CmpEQ(alpha, *Pointer<Short4>(data + OFFSET(DrawData,factor.alphaReference4)));
- aMask = SignMask(Pack(cmp, Short4(0x0000)));
+ aMask = SignMask(PackSigned(cmp, Short4(0x0000)));
break;
case ALPHA_NOTEQUAL: // a != b ~ !(a == b)
cmp = CmpEQ(alpha, *Pointer<Short4>(data + OFFSET(DrawData,factor.alphaReference4))) ^ Short4(0xFFFFu); // FIXME
- aMask = SignMask(Pack(cmp, Short4(0x0000)));
+ aMask = SignMask(PackSigned(cmp, Short4(0x0000)));
break;
case ALPHA_LESS: // a < b ~ b > a
cmp = CmpGT(*Pointer<Short4>(data + OFFSET(DrawData,factor.alphaReference4)), alpha);
- aMask = SignMask(Pack(cmp, Short4(0x0000)));
+ aMask = SignMask(PackSigned(cmp, Short4(0x0000)));
break;
case ALPHA_GREATEREQUAL: // a >= b ~ (a > b) || (a == b) ~ !(b > a) // TODO: Approximate
equal = CmpEQ(alpha, *Pointer<Short4>(data + OFFSET(DrawData,factor.alphaReference4)));
cmp = CmpGT(alpha, *Pointer<Short4>(data + OFFSET(DrawData,factor.alphaReference4)));
cmp |= equal;
- aMask = SignMask(Pack(cmp, Short4(0x0000)));
+ aMask = SignMask(PackSigned(cmp, Short4(0x0000)));
break;
case ALPHA_LESSEQUAL: // a <= b ~ !(a > b)
cmp = CmpGT(alpha, *Pointer<Short4>(data + OFFSET(DrawData,factor.alphaReference4))) ^ Short4(0xFFFFu); // FIXME
- aMask = SignMask(Pack(cmp, Short4(0x0000)));
+ aMask = SignMask(PackSigned(cmp, Short4(0x0000)));
break;
case ALPHA_GREATER: // a > b
cmp = CmpGT(alpha, *Pointer<Short4>(data + OFFSET(DrawData,factor.alphaReference4)));
- aMask = SignMask(Pack(cmp, Short4(0x0000)));
+ aMask = SignMask(PackSigned(cmp, Short4(0x0000)));
break;
default:
ASSERT(false);
@@ -1000,7 +991,7 @@
bool PixelRoutine::isSRGB(int index) const
{
- return state.targetFormat[index] == FORMAT_SRGB8_A8 || state.targetFormat[index] == FORMAT_SRGB8_X8;
+ return Surface::isSRGBformat(state.targetFormat[index]);
}
void PixelRoutine::readPixel(int index, Pointer<Byte> &cBuffer, Int &x, Vector4s &pixel)
@@ -1071,6 +1062,16 @@
pixel.y = Short4(0x0000);
pixel.z = Short4(0x0000);
break;
+ case FORMAT_R8:
+ buffer = cBuffer + 1 * x;
+ pixel.x = Insert(pixel.x, *Pointer<Short>(buffer), 0);
+ buffer += *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index]));
+ pixel.x = Insert(pixel.x, *Pointer<Short>(buffer), 1);
+ pixel.x = UnpackLow(As<Byte8>(pixel.x), As<Byte8>(pixel.x));
+ pixel.y = Short4(0x0000);
+ pixel.z = Short4(0x0000);
+ pixel.w = Short4(0xFFFFu);
+ break;
case FORMAT_X8R8G8B8:
buffer = cBuffer + 4 * x;
c01 = *Pointer<Short4>(buffer);
@@ -1089,6 +1090,16 @@
pixel.z = UnpackLow(As<Byte8>(pixel.z), As<Byte8>(pixel.z));
pixel.w = Short4(0xFFFFu);
break;
+ case FORMAT_G8R8:
+ buffer = cBuffer + 2 * x;
+ c01 = As<Short4>(Insert(As<Int2>(c01), *Pointer<Int>(buffer), 0));
+ buffer += *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index]));
+ c01 = As<Short4>(Insert(As<Int2>(c01), *Pointer<Int>(buffer), 1));
+ pixel.x = (c01 & Short4(0x00FFu)) | (c01 << 8);
+ pixel.y = (c01 & Short4(0xFF00u)) | As<Short4>(As<UShort4>(c01) >> 8);
+ pixel.z = Short4(0x0000u);
+ pixel.w = Short4(0xFFFFu);
+ break;
case FORMAT_X8B8G8R8:
case FORMAT_SRGB8_X8:
buffer = cBuffer + 4 * x;
@@ -1447,8 +1458,8 @@
current.y = As<Short4>(As<UShort4>(current.y) >> 8);
current.z = As<Short4>(As<UShort4>(current.z) >> 8);
- current.z = As<Short4>(Pack(As<UShort4>(current.z), As<UShort4>(current.x)));
- current.y = As<Short4>(Pack(As<UShort4>(current.y), As<UShort4>(current.y)));
+ current.z = As<Short4>(PackUnsigned(current.z, current.x));
+ current.y = As<Short4>(PackUnsigned(current.y, current.y));
current.x = current.z;
current.z = UnpackLow(As<Byte8>(current.z), As<Byte8>(current.y));
@@ -1464,8 +1475,8 @@
current.z = As<Short4>(As<UShort4>(current.z) >> 8);
current.w = As<Short4>(As<UShort4>(current.w) >> 8);
- current.z = As<Short4>(Pack(As<UShort4>(current.z), As<UShort4>(current.x)));
- current.y = As<Short4>(Pack(As<UShort4>(current.y), As<UShort4>(current.w)));
+ current.z = As<Short4>(PackUnsigned(current.z, current.x));
+ current.y = As<Short4>(PackUnsigned(current.y, current.w));
current.x = current.z;
current.z = UnpackLow(As<Byte8>(current.z), As<Byte8>(current.y));
@@ -1485,8 +1496,8 @@
current.y = As<Short4>(As<UShort4>(current.y) >> 8);
current.z = As<Short4>(As<UShort4>(current.z) >> 8);
- current.z = As<Short4>(Pack(As<UShort4>(current.x), As<UShort4>(current.z)));
- current.y = As<Short4>(Pack(As<UShort4>(current.y), As<UShort4>(current.y)));
+ current.z = As<Short4>(PackUnsigned(current.x, current.z));
+ current.y = As<Short4>(PackUnsigned(current.y, current.y));
current.x = current.z;
current.z = UnpackLow(As<Byte8>(current.z), As<Byte8>(current.y));
@@ -1502,8 +1513,8 @@
current.z = As<Short4>(As<UShort4>(current.z) >> 8);
current.w = As<Short4>(As<UShort4>(current.w) >> 8);
- current.z = As<Short4>(Pack(As<UShort4>(current.x), As<UShort4>(current.z)));
- current.y = As<Short4>(Pack(As<UShort4>(current.y), As<UShort4>(current.w)));
+ current.z = As<Short4>(PackUnsigned(current.x, current.z));
+ current.y = As<Short4>(PackUnsigned(current.y, current.w));
current.x = current.z;
current.z = UnpackLow(As<Byte8>(current.z), As<Byte8>(current.y));
@@ -1516,17 +1527,17 @@
case FORMAT_G8R8:
current.x = As<Short4>(As<UShort4>(current.x) >> 8);
current.y = As<Short4>(As<UShort4>(current.y) >> 8);
- current.x = As<Short4>(Pack(As<UShort4>(current.x), As<UShort4>(current.x)));
- current.y = As<Short4>(Pack(As<UShort4>(current.y), As<UShort4>(current.y)));
+ current.x = As<Short4>(PackUnsigned(current.x, current.x));
+ current.y = As<Short4>(PackUnsigned(current.y, current.y));
current.x = UnpackLow(As<Byte8>(current.x), As<Byte8>(current.y));
break;
case FORMAT_R8:
current.x = As<Short4>(As<UShort4>(current.x) >> 8);
- current.x = As<Short4>(Pack(As<UShort4>(current.x), As<UShort4>(current.x)));
+ current.x = As<Short4>(PackUnsigned(current.x, current.x));
break;
case FORMAT_A8:
current.w = As<Short4>(As<UShort4>(current.w) >> 8);
- current.w = As<Short4>(Pack(As<UShort4>(current.w), As<UShort4>(current.w)));
+ current.w = As<Short4>(PackUnsigned(current.w, current.w));
break;
case FORMAT_G16R16:
current.z = current.x;
@@ -1753,7 +1764,6 @@
value = Insert(value, *Pointer<Short>(buffer), 0);
Int pitch = *Pointer<Int>(data + OFFSET(DrawData, colorPitchB[index]));
value = Insert(value, *Pointer<Short>(buffer + pitch), 1);
- value = UnpackLow(As<Byte8>(value), As<Byte8>(value));
current.x &= *Pointer<Short4>(constants + OFFSET(Constants, maskB4Q) + 8 * xMask);
value &= *Pointer<Short4>(constants + OFFSET(Constants, invMaskB4Q) + 8 * xMask);
@@ -1771,7 +1781,6 @@
value = Insert(value, *Pointer<Short>(buffer), 0);
Int pitch = *Pointer<Int>(data + OFFSET(DrawData,colorPitchB[index]));
value = Insert(value, *Pointer<Short>(buffer + pitch), 1);
- value = UnpackLow(As<Byte8>(value), As<Byte8>(value));
current.w &= *Pointer<Short4>(constants + OFFSET(Constants,maskB4Q) + 8 * xMask);
value &= *Pointer<Short4>(constants + OFFSET(Constants,invMaskB4Q) + 8 * xMask);
@@ -2071,6 +2080,7 @@
break;
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_A32B32G32R32I:
case FORMAT_A32B32G32R32UI:
buffer = cBuffer;
@@ -2080,7 +2090,8 @@
pixel.z = *Pointer<Float4>(buffer + 16 * x, 16);
pixel.w = *Pointer<Float4>(buffer + 16 * x + 16, 16);
transpose4x4(pixel.x, pixel.y, pixel.z, pixel.w);
- if(state.targetFormat[index] == FORMAT_X32B32G32R32F)
+ if(state.targetFormat[index] == FORMAT_X32B32G32R32F ||
+ state.targetFormat[index] == FORMAT_X32B32G32R32F_UNSIGNED)
{
pixel.w = Float4(1.0f);
}
@@ -2232,6 +2243,7 @@
break;
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_A32B32G32R32I:
case FORMAT_A32B32G32R32UI:
case FORMAT_A16B16G16R16I:
@@ -2362,11 +2374,11 @@
Short4 tmpCol = Short4(As<Int4>(oC.x));
if(state.targetFormat[index] == FORMAT_R8I)
{
- tmpCol = As<Short4>(Pack(tmpCol, tmpCol));
+ tmpCol = As<Short4>(PackSigned(tmpCol, tmpCol));
}
else
{
- tmpCol = As<Short4>(Pack(As<UShort4>(tmpCol), As<UShort4>(tmpCol)));
+ tmpCol = As<Short4>(PackUnsigned(tmpCol, tmpCol));
}
packedCol = Extract(As<Int2>(tmpCol), 0);
@@ -2461,11 +2473,11 @@
if(state.targetFormat[index] == FORMAT_G8R8I)
{
- packedCol = As<Int2>(Pack(Short4(As<Int4>(oC.x)), Short4(As<Int4>(oC.y))));
+ packedCol = As<Int2>(PackSigned(Short4(As<Int4>(oC.x)), Short4(As<Int4>(oC.y))));
}
else
{
- packedCol = As<Int2>(Pack(UShort4(As<Int4>(oC.x)), UShort4(As<Int4>(oC.y))));
+ packedCol = As<Int2>(PackUnsigned(Short4(As<Int4>(oC.x)), Short4(As<Int4>(oC.y))));
}
UInt2 mergedMask = *Pointer<UInt2>(constants + OFFSET(Constants, maskW4Q) + xMask * 8);
@@ -2485,6 +2497,7 @@
break;
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_A32B32G32R32I:
case FORMAT_A32B32G32R32UI:
buffer = cBuffer + 16 * x;
@@ -2599,11 +2612,11 @@
if(state.targetFormat[index] == FORMAT_A8B8G8R8I)
{
- packedCol = As<UInt2>(Pack(Short4(As<Int4>(oC.x)), Short4(As<Int4>(oC.y))));
+ packedCol = As<UInt2>(PackSigned(Short4(As<Int4>(oC.x)), Short4(As<Int4>(oC.y))));
}
else
{
- packedCol = As<UInt2>(Pack(UShort4(As<Int4>(oC.x)), UShort4(As<Int4>(oC.y))));
+ packedCol = As<UInt2>(PackUnsigned(Short4(As<Int4>(oC.x)), Short4(As<Int4>(oC.y))));
}
value = *Pointer<UInt2>(buffer, 16);
mergedMask = *Pointer<UInt2>(constants + OFFSET(Constants, maskD01Q) + xMask * 8);
@@ -2617,11 +2630,11 @@
if(state.targetFormat[index] == FORMAT_A8B8G8R8I)
{
- packedCol = As<UInt2>(Pack(Short4(As<Int4>(oC.z)), Short4(As<Int4>(oC.w))));
+ packedCol = As<UInt2>(PackSigned(Short4(As<Int4>(oC.z)), Short4(As<Int4>(oC.w))));
}
else
{
- packedCol = As<UInt2>(Pack(UShort4(As<Int4>(oC.z)), UShort4(As<Int4>(oC.w))));
+ packedCol = As<UInt2>(PackUnsigned(Short4(As<Int4>(oC.z)), Short4(As<Int4>(oC.w))));
}
value = *Pointer<UInt2>(buffer, 16);
mergedMask = *Pointer<UInt2>(constants + OFFSET(Constants, maskD23Q) + xMask * 8);
@@ -2644,17 +2657,12 @@
void PixelRoutine::sRGBtoLinear16_12_16(Vector4s &c)
{
+ Pointer<Byte> LUT = constants + OFFSET(Constants,sRGBtoLinear12_16);
+
c.x = As<UShort4>(c.x) >> 4;
c.y = As<UShort4>(c.y) >> 4;
c.z = As<UShort4>(c.z) >> 4;
- sRGBtoLinear12_16(c);
- }
-
- void PixelRoutine::sRGBtoLinear12_16(Vector4s &c)
- {
- Pointer<Byte> LUT = constants + OFFSET(Constants,sRGBtoLinear12_16);
-
c.x = Insert(c.x, *Pointer<Short>(LUT + 2 * Int(Extract(c.x, 0))), 0);
c.x = Insert(c.x, *Pointer<Short>(LUT + 2 * Int(Extract(c.x, 1))), 1);
c.x = Insert(c.x, *Pointer<Short>(LUT + 2 * Int(Extract(c.x, 2))), 2);
diff --git a/src/Shader/PixelRoutine.hpp b/src/Shader/PixelRoutine.hpp
index d57f2cb..1cd076e 100644
--- a/src/Shader/PixelRoutine.hpp
+++ b/src/Shader/PixelRoutine.hpp
@@ -15,7 +15,7 @@
#ifndef sw_PixelRoutine_hpp
#define sw_PixelRoutine_hpp
-#include "QuadRasterizer.hpp"
+#include "Renderer/QuadRasterizer.hpp"
namespace sw
{
@@ -65,8 +65,6 @@
UShort4 convertFixed16(Float4 &cf, bool saturate = true);
void linearToSRGB12_16(Vector4s &c);
- SamplerCore *sampler[TEXTURE_IMAGE_UNITS];
-
private:
Float4 interpolateCentroid(Float4 &x, Float4 &y, Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective);
void stencilTest(Pointer<Byte> &sBuffer, int q, Int &x, Int &sMask, Int &cMask);
@@ -85,7 +83,6 @@
void writeDepth(Pointer<Byte> &zBuffer, int q, Int &x, Float4 &z, Int &zMask);
void sRGBtoLinear16_12_16(Vector4s &c);
- void sRGBtoLinear12_16(Vector4s &c);
void linearToSRGB16_12_16(Vector4s &c);
Float4 sRGBtoLinear(const Float4 &x);
diff --git a/src/Shader/PixelShader.cpp b/src/Shader/PixelShader.cpp
index c659248..9e281d9 100644
--- a/src/Shader/PixelShader.cpp
+++ b/src/Shader/PixelShader.cpp
@@ -14,7 +14,7 @@
#include "PixelShader.hpp"
-#include "Debug.hpp"
+#include "Common/Debug.hpp"
#include <string.h>
@@ -22,7 +22,7 @@
{
PixelShader::PixelShader(const PixelShader *ps) : Shader()
{
- version = 0x0300;
+ shaderModel = 0x0300;
vPosDeclared = false;
vFaceDeclared = false;
centroid = false;
@@ -167,11 +167,11 @@
{
zOverride = false;
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->opcode == Shader::OPCODE_TEXM3X2DEPTH ||
- instruction[i]->opcode == Shader::OPCODE_TEXDEPTH ||
- instruction[i]->dst.type == Shader::PARAMETER_DEPTHOUT)
+ if(inst->opcode == Shader::OPCODE_TEXM3X2DEPTH ||
+ inst->opcode == Shader::OPCODE_TEXDEPTH ||
+ inst->dst.type == Shader::PARAMETER_DEPTHOUT)
{
zOverride = true;
@@ -184,10 +184,10 @@
{
kill = false;
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->opcode == Shader::OPCODE_TEXKILL ||
- instruction[i]->opcode == Shader::OPCODE_DISCARD)
+ if(inst->opcode == Shader::OPCODE_TEXKILL ||
+ inst->opcode == Shader::OPCODE_DISCARD)
{
kill = true;
@@ -198,7 +198,7 @@
void PixelShader::analyzeInterpolants()
{
- if(version < 0x0300)
+ if(shaderModel < 0x0300)
{
// Set default mapping; disable unused interpolants below
input[0][0] = Semantic(Shader::USAGE_COLOR, 0);
@@ -226,25 +226,25 @@
samplerType[i] = Shader::SAMPLER_UNKNOWN;
}
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->dst.type == Shader::PARAMETER_SAMPLER)
+ if(inst->dst.type == Shader::PARAMETER_SAMPLER)
{
- int sampler = instruction[i]->dst.index;
+ int sampler = inst->dst.index;
- samplerType[sampler] = instruction[i]->samplerType;
+ samplerType[sampler] = inst->samplerType;
}
}
bool interpolant[MAX_FRAGMENT_INPUTS][4] = {{false}}; // Interpolants in use
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->dst.type == Shader::PARAMETER_TEXTURE)
+ if(inst->dst.type == Shader::PARAMETER_TEXTURE)
{
- int index = instruction[i]->dst.index + 2;
+ int index = inst->dst.index + 2;
- switch(instruction[i]->opcode)
+ switch(inst->opcode)
{
case Shader::OPCODE_TEX:
case Shader::OPCODE_TEXBEM:
@@ -288,7 +288,7 @@
case Shader::OPCODE_DCL:
break; // Ignore
default: // Arithmetic instruction
- if(version >= 0x0104)
+ if(shaderModel >= 0x0104)
{
ASSERT(false);
}
@@ -297,38 +297,41 @@
for(int argument = 0; argument < 4; argument++)
{
- if(instruction[i]->src[argument].type == Shader::PARAMETER_INPUT ||
- instruction[i]->src[argument].type == Shader::PARAMETER_TEXTURE)
+ if(inst->src[argument].type == Shader::PARAMETER_INPUT ||
+ inst->src[argument].type == Shader::PARAMETER_TEXTURE)
{
- int index = instruction[i]->src[argument].index;
- int swizzle = instruction[i]->src[argument].swizzle;
- int mask = instruction[i]->dst.mask;
+ int index = inst->src[argument].index;
+ int swizzle = inst->src[argument].swizzle;
+ int mask = inst->dst.mask;
- if(instruction[i]->src[argument].type == Shader::PARAMETER_TEXTURE)
+ if(inst->src[argument].type == Shader::PARAMETER_TEXTURE)
{
index += 2;
}
- switch(instruction[i]->opcode)
+ switch(inst->opcode)
{
case Shader::OPCODE_TEX:
case Shader::OPCODE_TEXLDD:
case Shader::OPCODE_TEXLDL:
+ case Shader::OPCODE_TEXLOD:
+ case Shader::OPCODE_TEXBIAS:
case Shader::OPCODE_TEXOFFSET:
- case Shader::OPCODE_TEXLDLOFFSET:
+ case Shader::OPCODE_TEXOFFSETBIAS:
+ case Shader::OPCODE_TEXLODOFFSET:
case Shader::OPCODE_TEXELFETCH:
case Shader::OPCODE_TEXELFETCHOFFSET:
case Shader::OPCODE_TEXGRAD:
case Shader::OPCODE_TEXGRADOFFSET:
{
- int sampler = instruction[i]->src[1].index;
+ int sampler = inst->src[1].index;
switch(samplerType[sampler])
{
case Shader::SAMPLER_UNKNOWN:
- if(version == 0x0104)
+ if(shaderModel == 0x0104)
{
- if((instruction[i]->src[0].swizzle & 0x30) == 0x20) // .xyz
+ if((inst->src[0].swizzle & 0x30) == 0x20) // .xyz
{
interpolant[index][0] = true;
interpolant[index][1] = true;
@@ -367,24 +370,24 @@
ASSERT(false);
}
- if(instruction[i]->bias)
+ if(inst->bias)
{
interpolant[index][3] = true;
}
- if(instruction[i]->project)
+ if(inst->project)
{
interpolant[index][3] = true;
}
- if(version == 0x0104 && instruction[i]->opcode == Shader::OPCODE_TEX)
+ if(shaderModel == 0x0104 && inst->opcode == Shader::OPCODE_TEX)
{
- if(instruction[i]->src[0].modifier == Shader::MODIFIER_DZ)
+ if(inst->src[0].modifier == Shader::MODIFIER_DZ)
{
interpolant[index][2] = true;
}
- if(instruction[i]->src[0].modifier == Shader::MODIFIER_DW)
+ if(inst->src[0].modifier == Shader::MODIFIER_DW)
{
interpolant[index][3] = true;
}
@@ -680,25 +683,25 @@
}
else // Shader Model 3.0 input declaration; v# indexable
{
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->opcode == Shader::OPCODE_DCL)
+ if(inst->opcode == Shader::OPCODE_DCL)
{
- if(instruction[i]->dst.type == Shader::PARAMETER_INPUT)
+ if(inst->dst.type == Shader::PARAMETER_INPUT)
{
- unsigned char usage = instruction[i]->usage;
- unsigned char index = instruction[i]->usageIndex;
- unsigned char mask = instruction[i]->dst.mask;
- unsigned char reg = instruction[i]->dst.index;
+ unsigned char usage = inst->usage;
+ unsigned char index = inst->usageIndex;
+ unsigned char mask = inst->dst.mask;
+ unsigned char reg = inst->dst.index;
- if(mask & 0x01) input[reg][0] = Semantic(usage, index);
+ if(mask & 0x01) input[reg][0] = Semantic(usage, index);
if(mask & 0x02) input[reg][1] = Semantic(usage, index);
if(mask & 0x04) input[reg][2] = Semantic(usage, index);
- if(mask & 0x08) input[reg][3] = Semantic(usage, index);
+ if(mask & 0x08) input[reg][3] = Semantic(usage, index);
}
- else if(instruction[i]->dst.type == Shader::PARAMETER_MISCTYPE)
+ else if(inst->dst.type == Shader::PARAMETER_MISCTYPE)
{
- unsigned char index = instruction[i]->dst.index;
+ unsigned char index = inst->dst.index;
if(index == Shader::VPosIndex)
{
@@ -714,16 +717,16 @@
}
}
- if(version >= 0x0200)
+ if(shaderModel >= 0x0200)
{
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->opcode == Shader::OPCODE_DCL)
+ if(inst->opcode == Shader::OPCODE_DCL)
{
- bool centroid = instruction[i]->dst.centroid;
- unsigned char reg = instruction[i]->dst.index;
+ bool centroid = inst->dst.centroid;
+ unsigned char reg = inst->dst.index;
- switch(instruction[i]->dst.type)
+ switch(inst->dst.type)
{
case Shader::PARAMETER_INPUT:
input[reg][0].centroid = centroid;
diff --git a/src/Shader/SamplerCore.cpp b/src/Shader/SamplerCore.cpp
index 62f76fa..8fa378f 100644
--- a/src/Shader/SamplerCore.cpp
+++ b/src/Shader/SamplerCore.cpp
@@ -15,7 +15,7 @@
#include "SamplerCore.hpp"
#include "Constants.hpp"
-#include "Debug.hpp"
+#include "Common/Debug.hpp"
namespace
{
@@ -56,13 +56,15 @@
{
}
- void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy)
+ Vector4s SamplerCore::sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy)
{
- sampleTexture(texture, c, u, v, w, q, dsx, dsy, dsx, Implicit, true);
+ return sampleTexture(texture, u, v, w, q, q, dsx, dsy, (dsx), Implicit, true);
}
- void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function, bool fixed12)
+ Vector4s SamplerCore::sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function, bool fixed12)
{
+ Vector4s c;
+
#if PERF_PROFILE
AddAtomic(Pointer<Long>(&profiler.texOperations), 4);
@@ -72,10 +74,6 @@
}
#endif
- Float4 uuuu = u;
- Float4 vvvv = v;
- Float4 wwww = w;
-
if(state.textureType == TEXTURE_NULL)
{
c.x = Short4(0x0000);
@@ -93,84 +91,59 @@
}
else
{
+ Float4 uuuu = u;
+ Float4 vvvv = v;
+ Float4 wwww = w;
+ Float4 qqqq = q;
+
Int face[4];
- Float4 lodX;
- Float4 lodY;
- Float4 lodZ;
-
- if(state.textureType == TEXTURE_CUBE)
- {
- cubeFace(face, uuuu, vvvv, lodX, lodY, lodZ, u, v, w);
- }
-
Float lod;
Float anisotropy;
Float4 uDelta;
Float4 vDelta;
- Float lodBias = (function == Fetch) ? Float4(As<Int4>(q)).x : q.x;
if(state.textureType != TEXTURE_3D)
{
if(state.textureType != TEXTURE_CUBE)
{
- computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, lodBias, dsx, dsy, function);
+ computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, bias.x, dsx, dsy, function);
}
else
{
- computeLodCube(texture, lod, lodX, lodY, lodZ, lodBias, dsx, dsy, function);
+ Float4 M;
+ cubeFace(face, uuuu, vvvv, u, v, w, M);
+ computeLodCube(texture, lod, u, v, w, bias.x, dsx, dsy, M, function);
}
}
else
{
- computeLod3D(texture, lod, uuuu, vvvv, wwww, lodBias, dsx, dsy, function);
+ computeLod3D(texture, lod, uuuu, vvvv, wwww, bias.x, dsx, dsy, function);
}
if(!hasFloatTexture())
{
- sampleFilter(texture, c, uuuu, vvvv, wwww, offset, lod, anisotropy, uDelta, vDelta, face, function);
+ c = sampleFilter(texture, uuuu, vvvv, wwww, offset, lod, anisotropy, uDelta, vDelta, face, function);
}
else
{
- Vector4f cf;
-
- sampleFloatFilter(texture, cf, uuuu, vvvv, wwww, offset, lod, anisotropy, uDelta, vDelta, face, function);
+ Vector4f cf = sampleFloatFilter(texture, uuuu, vvvv, wwww, qqqq, offset, lod, anisotropy, uDelta, vDelta, face, function);
convertFixed12(c, cf);
}
- if(fixed12 && !hasFloatTexture())
+ if(fixed12)
{
- if(has16bitTextureFormat())
+ if(!hasFloatTexture())
{
- switch(state.textureFormat)
+ if(state.textureFormat == FORMAT_R5G6B5)
{
- case FORMAT_R5G6B5:
- if(state.sRGB)
- {
- sRGBtoLinear16_5_12(c.x);
- sRGBtoLinear16_6_12(c.y);
- sRGBtoLinear16_5_12(c.z);
- }
- else
- {
- c.x = MulHigh(As<UShort4>(c.x), UShort4(0x10000000 / 0xF800));
- c.y = MulHigh(As<UShort4>(c.y), UShort4(0x10000000 / 0xFC00));
- c.z = MulHigh(As<UShort4>(c.z), UShort4(0x10000000 / 0xF800));
- }
- break;
- default:
- ASSERT(false);
+ c.x = MulHigh(As<UShort4>(c.x), UShort4(0x10000000 / 0xF800));
+ c.y = MulHigh(As<UShort4>(c.y), UShort4(0x10000000 / 0xFC00));
+ c.z = MulHigh(As<UShort4>(c.z), UShort4(0x10000000 / 0xF800));
}
- }
- else
- {
- for(int component = 0; component < textureComponentCount(); component++)
+ else
{
- if(state.sRGB && isRGBComponent(component))
- {
- sRGBtoLinear16_8_12(c[component]); // FIXME: Perform linearization at surface level for read-only textures
- }
- else
+ for(int component = 0; component < textureComponentCount(); component++)
{
if(hasUnsignedTextureComponent(component))
{
@@ -183,122 +156,128 @@
}
}
}
- }
- if(fixed12 && state.textureFilter != FILTER_GATHER)
- {
- int componentCount = textureComponentCount();
- short defaultColorValue = colorsDefaultToZero ? 0x0000 : 0x1000;
-
- switch(state.textureFormat)
+ if(state.textureFilter != FILTER_GATHER)
{
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
- case FORMAT_R8:
- case FORMAT_R5G6B5:
- case FORMAT_G8R8:
- case FORMAT_R8I:
- case FORMAT_R8UI:
- case FORMAT_G8R8I:
- case FORMAT_G8R8UI:
- case FORMAT_X8B8G8R8I:
- case FORMAT_X8B8G8R8UI:
- case FORMAT_A8B8G8R8I:
- case FORMAT_A8B8G8R8UI:
- case FORMAT_R16I:
- case FORMAT_R16UI:
- case FORMAT_G16R16:
- case FORMAT_G16R16I:
- case FORMAT_G16R16UI:
- case FORMAT_X16B16G16R16I:
- case FORMAT_X16B16G16R16UI:
- case FORMAT_A16B16G16R16:
- case FORMAT_A16B16G16R16I:
- case FORMAT_A16B16G16R16UI:
- case FORMAT_R32I:
- case FORMAT_R32UI:
- case FORMAT_G32R32I:
- case FORMAT_G32R32UI:
- case FORMAT_X32B32G32R32I:
- case FORMAT_X32B32G32R32UI:
- case FORMAT_A32B32G32R32I:
- case FORMAT_A32B32G32R32UI:
- case FORMAT_X8R8G8B8:
- case FORMAT_X8B8G8R8:
- case FORMAT_A8R8G8B8:
- case FORMAT_A8B8G8R8:
- case FORMAT_SRGB8_X8:
- case FORMAT_SRGB8_A8:
- case FORMAT_V8U8:
- case FORMAT_Q8W8V8U8:
- case FORMAT_X8L8V8U8:
- case FORMAT_V16U16:
- case FORMAT_A16W16V16U16:
- case FORMAT_Q16W16V16U16:
- case FORMAT_YV12_BT601:
- case FORMAT_YV12_BT709:
- case FORMAT_YV12_JFIF:
- if(componentCount < 2) c.y = Short4(defaultColorValue);
- if(componentCount < 3) c.z = Short4(defaultColorValue);
- if(componentCount < 4) c.w = Short4(0x1000);
- break;
- case FORMAT_A8:
- c.w = c.x;
- c.x = Short4(0x0000);
- c.y = Short4(0x0000);
- c.z = Short4(0x0000);
- break;
- case FORMAT_L8:
- case FORMAT_L16:
- c.y = c.x;
- c.z = c.x;
- c.w = Short4(0x1000);
- break;
- case FORMAT_A8L8:
- c.w = c.y;
- c.y = c.x;
- c.z = c.x;
- break;
- case FORMAT_R32F:
- c.y = Short4(defaultColorValue);
- case FORMAT_G32R32F:
- c.z = Short4(defaultColorValue);
- case FORMAT_X32B32G32R32F:
- c.w = Short4(0x1000);
- case FORMAT_A32B32G32R32F:
- break;
- case FORMAT_D32F:
- case FORMAT_D32F_LOCKABLE:
- case FORMAT_D32FS8_TEXTURE:
- case FORMAT_D32FS8_SHADOW:
- c.y = c.x;
- c.z = c.x;
- c.w = c.x;
- break;
- default:
- ASSERT(false);
+ int componentCount = textureComponentCount();
+ short defaultColorValue = colorsDefaultToZero ? 0x0000 : 0x1000;
+
+ switch(state.textureFormat)
+ {
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
+ case FORMAT_R8:
+ case FORMAT_R5G6B5:
+ case FORMAT_G8R8:
+ case FORMAT_R8I:
+ case FORMAT_R8UI:
+ case FORMAT_G8R8I:
+ case FORMAT_G8R8UI:
+ case FORMAT_X8B8G8R8I:
+ case FORMAT_X8B8G8R8UI:
+ case FORMAT_A8B8G8R8I:
+ case FORMAT_A8B8G8R8UI:
+ case FORMAT_R16I:
+ case FORMAT_R16UI:
+ case FORMAT_G16R16:
+ case FORMAT_G16R16I:
+ case FORMAT_G16R16UI:
+ case FORMAT_X16B16G16R16I:
+ case FORMAT_X16B16G16R16UI:
+ case FORMAT_A16B16G16R16:
+ case FORMAT_A16B16G16R16I:
+ case FORMAT_A16B16G16R16UI:
+ case FORMAT_R32I:
+ case FORMAT_R32UI:
+ case FORMAT_G32R32I:
+ case FORMAT_G32R32UI:
+ case FORMAT_X32B32G32R32I:
+ case FORMAT_X32B32G32R32UI:
+ case FORMAT_A32B32G32R32I:
+ case FORMAT_A32B32G32R32UI:
+ case FORMAT_X8R8G8B8:
+ case FORMAT_X8B8G8R8:
+ case FORMAT_A8R8G8B8:
+ case FORMAT_A8B8G8R8:
+ case FORMAT_SRGB8_X8:
+ case FORMAT_SRGB8_A8:
+ case FORMAT_V8U8:
+ case FORMAT_Q8W8V8U8:
+ case FORMAT_X8L8V8U8:
+ case FORMAT_V16U16:
+ case FORMAT_A16W16V16U16:
+ case FORMAT_Q16W16V16U16:
+ case FORMAT_YV12_BT601:
+ case FORMAT_YV12_BT709:
+ case FORMAT_YV12_JFIF:
+ if(componentCount < 2) c.y = Short4(defaultColorValue);
+ if(componentCount < 3) c.z = Short4(defaultColorValue);
+ if(componentCount < 4) c.w = Short4(0x1000);
+ break;
+ case FORMAT_A8:
+ c.w = c.x;
+ c.x = Short4(0x0000);
+ c.y = Short4(0x0000);
+ c.z = Short4(0x0000);
+ break;
+ case FORMAT_L8:
+ case FORMAT_L16:
+ c.y = c.x;
+ c.z = c.x;
+ c.w = Short4(0x1000);
+ break;
+ case FORMAT_A8L8:
+ c.w = c.y;
+ c.y = c.x;
+ c.z = c.x;
+ break;
+ case FORMAT_R32F:
+ c.y = Short4(defaultColorValue);
+ case FORMAT_G32R32F:
+ c.z = Short4(defaultColorValue);
+ case FORMAT_X32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
+ c.w = Short4(0x1000);
+ case FORMAT_A32B32G32R32F:
+ break;
+ case FORMAT_D32F:
+ case FORMAT_D32FS8:
+ case FORMAT_D32F_LOCKABLE:
+ case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
+ case FORMAT_D32FS8_SHADOW:
+ c.y = c.x;
+ c.z = c.x;
+ c.w = c.x;
+ break;
+ default:
+ ASSERT(false);
+ }
+ }
+
+ if((state.swizzleR != SWIZZLE_RED) ||
+ (state.swizzleG != SWIZZLE_GREEN) ||
+ (state.swizzleB != SWIZZLE_BLUE) ||
+ (state.swizzleA != SWIZZLE_ALPHA))
+ {
+ const Vector4s col(c);
+ applySwizzle(state.swizzleR, c.x, col);
+ applySwizzle(state.swizzleG, c.y, col);
+ applySwizzle(state.swizzleB, c.z, col);
+ applySwizzle(state.swizzleA, c.w, col);
}
}
}
- if(fixed12 &&
- ((state.swizzleR != SWIZZLE_RED) ||
- (state.swizzleG != SWIZZLE_GREEN) ||
- (state.swizzleB != SWIZZLE_BLUE) ||
- (state.swizzleA != SWIZZLE_ALPHA)))
- {
- const Vector4s col(c);
- applySwizzle(state.swizzleR, c.x, col);
- applySwizzle(state.swizzleG, c.y, col);
- applySwizzle(state.swizzleB, c.z, col);
- applySwizzle(state.swizzleA, c.w, col);
- }
+ return c;
}
- void SamplerCore::sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
+ Vector4f SamplerCore::sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{
+ Vector4f c;
+
#if PERF_PROFILE
AddAtomic(Pointer<Long>(&profiler.texOperations), 4);
@@ -317,47 +296,42 @@
}
else
{
- // FIXME: YUV and sRGB are not supported by the floating point path
- bool forceFloatFiltering = state.highPrecisionFiltering && !state.sRGB && !hasYuvFormat() && (state.textureFilter != FILTER_POINT);
- if(hasFloatTexture() || hasUnnormalizedIntegerTexture() || forceFloatFiltering) // FIXME: Mostly identical to integer sampling
+ // FIXME: YUV is not supported by the floating point path
+ bool forceFloatFiltering = state.highPrecisionFiltering && !hasYuvFormat() && (state.textureFilter != FILTER_POINT);
+ bool seamlessCube = (state.addressingModeU == ADDRESSING_SEAMLESS);
+ bool rectangleTexture = (state.textureType == TEXTURE_RECTANGLE);
+ if(hasFloatTexture() || hasUnnormalizedIntegerTexture() || forceFloatFiltering || seamlessCube || rectangleTexture) // FIXME: Mostly identical to integer sampling
{
Float4 uuuu = u;
Float4 vvvv = v;
Float4 wwww = w;
+ Float4 qqqq = q;
Int face[4];
- Float4 lodX;
- Float4 lodY;
- Float4 lodZ;
-
- if(state.textureType == TEXTURE_CUBE)
- {
- cubeFace(face, uuuu, vvvv, lodX, lodY, lodZ, u, v, w);
- }
-
Float lod;
Float anisotropy;
Float4 uDelta;
Float4 vDelta;
- Float lodBias = (function == Fetch) ? Float4(As<Int4>(q)).x : q.x;
if(state.textureType != TEXTURE_3D)
{
if(state.textureType != TEXTURE_CUBE)
{
- computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, lodBias, dsx, dsy, function);
+ computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, bias.x, dsx, dsy, function);
}
else
{
- computeLodCube(texture, lod, lodX, lodY, lodZ, lodBias, dsx, dsy, function);
+ Float4 M;
+ cubeFace(face, uuuu, vvvv, u, v, w, M);
+ computeLodCube(texture, lod, u, v, w, bias.x, dsx, dsy, M, function);
}
}
else
{
- computeLod3D(texture, lod, uuuu, vvvv, wwww, lodBias, dsx, dsy, function);
+ computeLod3D(texture, lod, uuuu, vvvv, wwww, bias.x, dsx, dsy, function);
}
- sampleFloatFilter(texture, c, uuuu, vvvv, wwww, offset, lod, anisotropy, uDelta, vDelta, face, function);
+ c = sampleFloatFilter(texture, uuuu, vvvv, wwww, qqqq, offset, lod, anisotropy, uDelta, vDelta, face, function);
if(!hasFloatTexture() && !hasUnnormalizedIntegerTexture())
{
@@ -385,56 +359,25 @@
}
else
{
- Vector4s cs;
+ Vector4s cs = sampleTexture(texture, u, v, w, q, bias, dsx, dsy, offset, function, false);
- sampleTexture(texture, cs, u, v, w, q, dsx, dsy, offset, function, false);
-
- if(has16bitTextureFormat())
+ if(state.textureFormat == FORMAT_R5G6B5)
{
- switch(state.textureFormat)
- {
- case FORMAT_R5G6B5:
- if(state.sRGB)
- {
- sRGBtoLinear16_5_12(cs.x);
- sRGBtoLinear16_6_12(cs.y);
- sRGBtoLinear16_5_12(cs.z);
-
- convertSigned12(c.x, cs.x);
- convertSigned12(c.y, cs.y);
- convertSigned12(c.z, cs.z);
- }
- else
- {
- c.x = Float4(As<UShort4>(cs.x)) * Float4(1.0f / 0xF800);
- c.y = Float4(As<UShort4>(cs.y)) * Float4(1.0f / 0xFC00);
- c.z = Float4(As<UShort4>(cs.z)) * Float4(1.0f / 0xF800);
- }
- break;
- default:
- ASSERT(false);
- }
+ c.x = Float4(As<UShort4>(cs.x)) * Float4(1.0f / 0xF800);
+ c.y = Float4(As<UShort4>(cs.y)) * Float4(1.0f / 0xFC00);
+ c.z = Float4(As<UShort4>(cs.z)) * Float4(1.0f / 0xF800);
}
else
{
for(int component = 0; component < textureComponentCount(); component++)
{
- // Normalized integer formats
- if(state.sRGB && isRGBComponent(component))
+ if(hasUnsignedTextureComponent(component))
{
- sRGBtoLinear16_8_12(cs[component]); // FIXME: Perform linearization at surface level for read-only textures
- convertSigned12(c[component], cs[component]);
+ convertUnsigned16(c[component], cs[component]);
}
else
{
- if(hasUnsignedTextureComponent(component))
- {
- convertUnsigned16(c[component], cs[component]);
- }
- else
- {
- convertSigned15(c[component], cs[component]);
- }
+ convertSigned15(c[component], cs[component]);
}
}
}
@@ -475,10 +418,10 @@
case FORMAT_A32B32G32R32I:
case FORMAT_A32B32G32R32UI:
break;
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_R8:
case FORMAT_R5G6B5:
case FORMAT_G8R8:
@@ -525,38 +468,45 @@
case FORMAT_G32R32F:
c.z = Float4(defaultColorValue);
case FORMAT_X32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
c.w = Float4(1.0f);
case FORMAT_A32B32G32R32F:
break;
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
- c.y = c.x;
- c.z = c.x;
- c.w = c.x;
+ c.y = Float4(0.0f);
+ c.z = Float4(0.0f);
+ c.w = Float4(1.0f);
break;
default:
ASSERT(false);
}
}
+
+ if((state.swizzleR != SWIZZLE_RED) ||
+ (state.swizzleG != SWIZZLE_GREEN) ||
+ (state.swizzleB != SWIZZLE_BLUE) ||
+ (state.swizzleA != SWIZZLE_ALPHA))
+ {
+ const Vector4f col(c);
+ applySwizzle(state.swizzleR, c.x, col);
+ applySwizzle(state.swizzleG, c.y, col);
+ applySwizzle(state.swizzleB, c.z, col);
+ applySwizzle(state.swizzleA, c.w, col);
+ }
}
- if((state.swizzleR != SWIZZLE_RED) ||
- (state.swizzleG != SWIZZLE_GREEN) ||
- (state.swizzleB != SWIZZLE_BLUE) ||
- (state.swizzleA != SWIZZLE_ALPHA))
- {
- const Vector4f col(c);
- applySwizzle(state.swizzleR, c.x, col);
- applySwizzle(state.swizzleG, c.y, col);
- applySwizzle(state.swizzleB, c.z, col);
- applySwizzle(state.swizzleA, c.w, col);
- }
+ return c;
}
- void SamplerCore::textureSize(Pointer<Byte> &texture, Vector4f &size, Float4 &lod)
+ Vector4f SamplerCore::textureSize(Pointer<Byte> &texture, Float4 &lod)
{
+ Vector4f size;
+
for(int i = 0; i < 4; ++i)
{
Int baseLevel = *Pointer<Int>(texture + OFFSET(Texture, baseLevel));
@@ -565,12 +515,14 @@
size.y = Insert(size.y, As<Float>(Int(*Pointer<Short>(mipmap + OFFSET(Mipmap, height)))), i);
size.z = Insert(size.z, As<Float>(Int(*Pointer<Short>(mipmap + OFFSET(Mipmap, depth)))), i);
}
+
+ return size;
}
void SamplerCore::border(Short4 &mask, Float4 &coordinates)
{
Int4 border = As<Int4>(CmpLT(Abs(coordinates - Float4(0.5f)), Float4(0.5f)));
- mask = As<Short4>(Int2(As<Int4>(Pack(border, border))));
+ mask = As<Short4>(Int2(As<Int4>(PackSigned(border, border))));
}
void SamplerCore::border(Int4 &mask, Float4 &coordinates)
@@ -615,20 +567,18 @@
return uvw;
}
- void SamplerCore::sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function)
+ Vector4s SamplerCore::sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function)
{
- sampleAniso(texture, c, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, false, function);
+ Vector4s c = sampleAniso(texture, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, false, function);
if(function == Fetch)
{
- return;
+ return c;
}
- if(state.mipmapFilter > MIPMAP_POINT)
+ if(state.mipmapFilter == MIPMAP_LINEAR)
{
- Vector4s cc;
-
- sampleAniso(texture, cc, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, true, function);
+ Vector4s cc = sampleAniso(texture, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, true, function);
lod *= Float(1 << 16);
@@ -714,13 +664,17 @@
c.z = (borderMask & c.z) | (~borderMask & (*Pointer<Short4>(texture + OFFSET(Texture,borderColor4[2])) >> (hasUnsignedTextureComponent(2) ? 0 : 1)));
c.w = (borderMask & c.w) | (~borderMask & (*Pointer<Short4>(texture + OFFSET(Texture,borderColor4[3])) >> (hasUnsignedTextureComponent(3) ? 0 : 1)));
}
+
+ return c;
}
- void SamplerCore::sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function)
+ Vector4s SamplerCore::sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function)
{
+ Vector4s c;
+
if(state.textureFilter != FILTER_ANISOTROPIC || function == Lod || function == Fetch)
{
- sampleQuad(texture, c, u, v, w, offset, lod, face, secondLOD, function);
+ c = sampleQuad(texture, u, v, w, offset, lod, face, secondLOD, function);
}
else
{
@@ -751,7 +705,7 @@
Do
{
- sampleQuad(texture, c, u0, v0, w, offset, lod, face, secondLOD, function);
+ c = sampleQuad(texture, u0, v0, w, offset, lod, face, secondLOD, function);
u0 += du;
v0 += dv;
@@ -770,22 +724,26 @@
if(hasUnsignedTextureComponent(2)) c.z = cSum.z; else c.z = AddSat(cSum.z, cSum.z);
if(hasUnsignedTextureComponent(3)) c.w = cSum.w; else c.w = AddSat(cSum.w, cSum.w);
}
+
+ return c;
}
- void SamplerCore::sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function)
+ Vector4s SamplerCore::sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function)
{
if(state.textureType != TEXTURE_3D)
{
- sampleQuad2D(texture, c, u, v, w, offset, lod, face, secondLOD, function);
+ return sampleQuad2D(texture, u, v, w, offset, lod, face, secondLOD, function);
}
else
{
- sample3D(texture, c, u, v, w, offset, lod, secondLOD, function);
+ return sample3D(texture, u, v, w, offset, lod, secondLOD, function);
}
}
- void SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function)
+ Vector4s SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function)
{
+ Vector4s c;
+
int componentCount = textureComponentCount();
bool gather = state.textureFilter == FILTER_GATHER;
@@ -973,10 +931,14 @@
c.w = c0.x;
}
}
+
+ return c;
}
- void SamplerCore::sample3D(Pointer<Byte> &texture, Vector4s &c_, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function)
+ Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function)
{
+ Vector4s c_;
+
int componentCount = textureComponentCount();
Pointer<Byte> mipmap;
@@ -1094,22 +1056,22 @@
if(componentCount >= 3) if(!hasUnsignedTextureComponent(2)) c_.z = AddSat(c_.z, c_.z);
if(componentCount >= 4) if(!hasUnsignedTextureComponent(3)) c_.w = AddSat(c_.w, c_.w);
}
+
+ return c_;
}
- void SamplerCore::sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function)
+ Vector4f SamplerCore::sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function)
{
- sampleFloatAniso(texture, c, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, false, function);
+ Vector4f c = sampleFloatAniso(texture, u, v, w, q, offset, lod, anisotropy, uDelta, vDelta, face, false, function);
if(function == Fetch)
{
- return;
+ return c;
}
- if(state.mipmapFilter > MIPMAP_POINT)
+ if(state.mipmapFilter == MIPMAP_LINEAR)
{
- Vector4f cc;
-
- sampleFloatAniso(texture, cc, u, v, w, offset, lod, anisotropy, uDelta, vDelta, face, true, function);
+ Vector4f cc = sampleFloatAniso(texture, u, v, w, q, offset, lod, anisotropy, uDelta, vDelta, face, true, function);
Float4 lod4 = Float4(Frac(lod));
@@ -1174,13 +1136,17 @@
c.z = As<Float4>((borderMask & As<Int4>(c.z)) | (~borderMask & *Pointer<Int4>(texture + OFFSET(Texture,borderColorF[2]))));
c.w = As<Float4>((borderMask & As<Int4>(c.w)) | (~borderMask & *Pointer<Int4>(texture + OFFSET(Texture,borderColorF[3]))));
}
+
+ return c;
}
- void SamplerCore::sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function)
+ Vector4f SamplerCore::sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function)
{
+ Vector4f c;
+
if(state.textureFilter != FILTER_ANISOTROPIC || function == Lod || function == Fetch)
{
- sampleFloat(texture, c, u, v, w, offset, lod, face, secondLOD, function);
+ c = sampleFloat(texture, u, v, w, q, offset, lod, face, secondLOD, function);
}
else
{
@@ -1209,7 +1175,7 @@
Do
{
- sampleFloat(texture, c, u0, v0, w, offset, lod, face, secondLOD, function);
+ c = sampleFloat(texture, u0, v0, w, q, offset, lod, face, secondLOD, function);
u0 += du;
v0 += dv;
@@ -1228,22 +1194,26 @@
c.z = cSum.z;
c.w = cSum.w;
}
+
+ return c;
}
- void SamplerCore::sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function)
+ Vector4f SamplerCore::sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function)
{
if(state.textureType != TEXTURE_3D)
{
- sampleFloat2D(texture, c, u, v, w, offset, lod, face, secondLOD, function);
+ return sampleFloat2D(texture, u, v, w, q, offset, lod, face, secondLOD, function);
}
else
{
- sampleFloat3D(texture, c, u, v, w, offset, lod, secondLOD, function);
+ return sampleFloat3D(texture, u, v, w, offset, lod, secondLOD, function);
}
}
- void SamplerCore::sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function)
+ Vector4f SamplerCore::sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function)
{
+ Vector4f c;
+
int componentCount = textureComponentCount();
bool gather = state.textureFilter == FILTER_GATHER;
@@ -1255,9 +1225,9 @@
Int4 x0, x1, y0, y1, z0;
Float4 fu, fv;
Int4 filter = computeFilterOffset(lod);
- address(w, z0, z0, fv, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW, function);
- address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV, function);
address(u, x0, x1, fu, mipmap, offset.x, filter, OFFSET(Mipmap, width), state.addressingModeU, function);
+ address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV, function);
+ address(w, z0, z0, fv, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW, function);
Int4 pitchP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, pitchP), 16);
y0 *= pitchP;
@@ -1269,16 +1239,16 @@
if(state.textureFilter == FILTER_POINT || (function == Fetch))
{
- c = sampleTexel(x0, y0, z0, w, mipmap, buffer, function);
+ c = sampleTexel(x0, y0, z0, q, mipmap, buffer, function);
}
else
{
y1 *= pitchP;
- Vector4f c0 = sampleTexel(x0, y0, z0, w, mipmap, buffer, function);
- Vector4f c1 = sampleTexel(x1, y0, z0, w, mipmap, buffer, function);
- Vector4f c2 = sampleTexel(x0, y1, z0, w, mipmap, buffer, function);
- Vector4f c3 = sampleTexel(x1, y1, z0, w, mipmap, buffer, function);
+ Vector4f c0 = sampleTexel(x0, y0, z0, q, mipmap, buffer, function);
+ Vector4f c1 = sampleTexel(x1, y0, z0, q, mipmap, buffer, function);
+ Vector4f c2 = sampleTexel(x0, y1, z0, q, mipmap, buffer, function);
+ Vector4f c3 = sampleTexel(x1, y1, z0, q, mipmap, buffer, function);
if(!gather) // Blend
{
@@ -1305,10 +1275,14 @@
c.w = c0.x;
}
}
+
+ return c;
}
- void SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function)
+ Vector4f SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function)
{
+ Vector4f c;
+
int componentCount = textureComponentCount();
Pointer<Byte> mipmap;
@@ -1385,6 +1359,8 @@
if(componentCount >= 3) c.z = c0.z + fw * (c4.z - c0.z);
if(componentCount >= 4) c.w = c0.w + fw * (c4.w - c0.w);
}
+
+ return c;
}
Float SamplerCore::log2sqrt(Float lod)
@@ -1397,13 +1373,22 @@
return lod;
}
+ Float SamplerCore::log2(Float lod)
+ {
+ lod *= lod; // Squaring doubles the exponent and produces an extra bit of precision.
+ lod = Float(As<Int>(lod)) - Float(0x3F800000); // Interpret as integer and subtract the exponent bias.
+ lod *= As<Float>(Int(0x33800000)); // Scale by 0.5 * 2^-23 (mantissa length).
+
+ return lod;
+ }
+
void SamplerCore::computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &uuuu, Float4 &vvvv, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function)
{
if(function != Lod && function != Fetch)
{
Float4 duvdxy;
- if(function != Grad)
+ if(function != Grad) // Implicit
{
duvdxy = Float4(uuuu.yz, vvvv.yz) - Float4(uuuu.xx, vvvv.xx);
}
@@ -1415,7 +1400,7 @@
duvdxy = Float4(dudxy.xz, dvdxy.xz);
}
- // Scale by texture dimensions and LOD
+ // Scale by texture dimensions and global LOD.
Float4 dUVdxy = duvdxy * *Pointer<Float4>(texture + OFFSET(Texture,widthHeightLOD));
Float4 dUV2dxy = dUVdxy * dUVdxy;
@@ -1449,55 +1434,124 @@
lod += lodBias;
}
}
- else
+ else if(function == Lod)
{
- lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
+ lod = lodBias;
}
+ else if(function == Fetch)
+ {
+ // TODO: Eliminate int-float-int conversion.
+ lod = Float(As<Int>(lodBias));
+ }
+ else if(function == Base)
+ {
+ lod = Float(0);
+ }
+ else assert(false);
lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
- void SamplerCore::computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &s, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function)
+ void SamplerCore::computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function)
{
if(function != Lod && function != Fetch)
{
- if(function != Grad)
+ Float4 dudxy, dvdxy, dsdxy;
+
+ if(function != Grad) // Implicit
{
- Float4 dudxy = u.ywyw - u;
- Float4 dvdxy = v.ywyw - v;
- Float4 dsdxy = s.ywyw - s;
+ Float4 U = u * M;
+ Float4 V = v * M;
+ Float4 W = w * M;
- // Scale by texture dimensions and LOD
- dudxy *= *Pointer<Float4>(texture + OFFSET(Texture,widthLOD));
- dvdxy *= *Pointer<Float4>(texture + OFFSET(Texture,widthLOD));
- dsdxy *= *Pointer<Float4>(texture + OFFSET(Texture,widthLOD));
-
- dudxy *= dudxy;
- dvdxy *= dvdxy;
- dsdxy *= dsdxy;
-
- dudxy += dvdxy;
- dudxy += dsdxy;
-
- lod = Max(Float(dudxy.x), Float(dudxy.y)); // FIXME: Max(dudxy.x, dudxy.y);
+ dudxy = Abs(U - U.xxxx);
+ dvdxy = Abs(V - V.xxxx);
+ dsdxy = Abs(W - W.xxxx);
}
else
{
- Float4 dudxy = Float4(dsx.x.xx, dsy.x.xx);
- Float4 dvdxy = Float4(dsx.y.xx, dsy.y.xx);
+ dudxy = Float4(dsx.x.xx, dsy.x.xx);
+ dvdxy = Float4(dsx.y.xx, dsy.y.xx);
+ dsdxy = Float4(dsx.z.xx, dsy.z.xx);
- Float4 duvdxy = Float4(dudxy.xz, dvdxy.xz);
-
- // Scale by texture dimensions and LOD
- Float4 dUVdxy = duvdxy * *Pointer<Float4>(texture + OFFSET(Texture,widthLOD));
-
- Float4 dUV2dxy = dUVdxy * dUVdxy;
- Float4 dUV2 = dUV2dxy.xy + dUV2dxy.zw;
-
- lod = Max(Float(dUV2.x), Float(dUV2.y)); // Square length of major axis
+ dudxy = Abs(dudxy * Float4(M.x));
+ dvdxy = Abs(dvdxy * Float4(M.x));
+ dsdxy = Abs(dsdxy * Float4(M.x));
}
+ // Compute the largest Manhattan distance in two dimensions.
+ // This takes the footprint across adjacent faces into account.
+ Float4 duvdxy = dudxy + dvdxy;
+ Float4 dusdxy = dudxy + dsdxy;
+ Float4 dvsdxy = dvdxy + dsdxy;
+
+ dudxy = Max(Max(duvdxy, dusdxy), dvsdxy);
+
+ lod = Max(Float(dudxy.y), Float(dudxy.z)); // FIXME: Max(dudxy.y, dudxy.z);
+
+ // Scale by texture dimension and global LOD.
+ lod *= *Pointer<Float>(texture + OFFSET(Texture,widthLOD));
+
+ lod = log2(lod);
+
+ if(function == Bias)
+ {
+ lod += lodBias;
+ }
+ }
+ else if(function == Lod)
+ {
+ lod = lodBias;
+ }
+ else if(function == Fetch)
+ {
+ // TODO: Eliminate int-float-int conversion.
+ lod = Float(As<Int>(lodBias));
+ }
+ else if(function == Base)
+ {
+ lod = Float(0);
+ }
+ else assert(false);
+
+ lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
+ lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
+ }
+
+ void SamplerCore::computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &uuuu, Float4 &vvvv, Float4 &wwww, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function)
+ {
+ if(function != Lod && function != Fetch)
+ {
+ Float4 dudxy, dvdxy, dsdxy;
+
+ if(function != Grad) // Implicit
+ {
+ dudxy = uuuu - uuuu.xxxx;
+ dvdxy = vvvv - vvvv.xxxx;
+ dsdxy = wwww - wwww.xxxx;
+ }
+ else
+ {
+ dudxy = Float4(dsx.x.xx, dsy.x.xx);
+ dvdxy = Float4(dsx.y.xx, dsy.y.xx);
+ dsdxy = Float4(dsx.z.xx, dsy.z.xx);
+ }
+
+ // Scale by texture dimensions and global LOD.
+ dudxy *= *Pointer<Float4>(texture + OFFSET(Texture,widthLOD));
+ dvdxy *= *Pointer<Float4>(texture + OFFSET(Texture,heightLOD));
+ dsdxy *= *Pointer<Float4>(texture + OFFSET(Texture,depthLOD));
+
+ dudxy *= dudxy;
+ dvdxy *= dvdxy;
+ dsdxy *= dsdxy;
+
+ dudxy += dvdxy;
+ dudxy += dsdxy;
+
+ lod = Max(Float(dudxy.y), Float(dudxy.z)); // FIXME: Max(dudxy.y, dudxy.z);
+
lod = log2sqrt(lod); // log2(sqrt(lod))
if(function == Bias)
@@ -1505,81 +1559,26 @@
lod += lodBias;
}
}
- else
+ else if(function == Lod)
{
- lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
+ lod = lodBias;
}
+ else if(function == Fetch)
+ {
+ // TODO: Eliminate int-float-int conversion.
+ lod = Float(As<Int>(lodBias));
+ }
+ else if(function == Base)
+ {
+ lod = Float(0);
+ }
+ else assert(false);
lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
- void SamplerCore::computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &uuuu, Float4 &vvvv, Float4 &wwww, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function)
- {
- if(state.mipmapFilter == MIPMAP_NONE)
- {
- }
- else // Point and linear filter
- {
- if(function != Lod && function != Fetch)
- {
- Float4 dudxy;
- Float4 dvdxy;
- Float4 dsdxy;
-
- if(function != Grad)
- {
- dudxy = uuuu.ywyw - uuuu;
- dvdxy = vvvv.ywyw - vvvv;
- dsdxy = wwww.ywyw - wwww;
- }
- else
- {
- dudxy = dsx.x;
- dvdxy = dsx.y;
- dsdxy = dsx.z;
-
- dudxy = Float4(dudxy.xx, dsy.x.xx);
- dvdxy = Float4(dvdxy.xx, dsy.y.xx);
- dsdxy = Float4(dsdxy.xx, dsy.z.xx);
-
- dudxy = Float4(dudxy.xz, dudxy.xz);
- dvdxy = Float4(dvdxy.xz, dvdxy.xz);
- dsdxy = Float4(dsdxy.xz, dsdxy.xz);
- }
-
- // Scale by texture dimensions and LOD
- dudxy *= *Pointer<Float4>(texture + OFFSET(Texture,widthLOD));
- dvdxy *= *Pointer<Float4>(texture + OFFSET(Texture,heightLOD));
- dsdxy *= *Pointer<Float4>(texture + OFFSET(Texture,depthLOD));
-
- dudxy *= dudxy;
- dvdxy *= dvdxy;
- dsdxy *= dsdxy;
-
- dudxy += dvdxy;
- dudxy += dsdxy;
-
- lod = Max(Float(dudxy.x), Float(dudxy.y)); // FIXME: Max(dudxy.x, dudxy.y);
-
- lod = log2sqrt(lod); // log2(sqrt(lod))
-
- if(function == Bias)
- {
- lod += lodBias;
- }
- }
- else
- {
- lod = lodBias + Float(*Pointer<Int>(texture + OFFSET(Texture,baseLevel)));
- }
-
- lod = Max(lod, *Pointer<Float>(texture + OFFSET(Texture, minLod)));
- lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
- }
- }
-
- void SamplerCore::cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &lodX, Float4 &lodY, Float4 &lodZ, Float4 &x, Float4 &y, Float4 &z)
+ void SamplerCore::cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M)
{
Int4 xn = CmpLT(x, Float4(0.0f)); // x < 0
Int4 yn = CmpLT(y, Float4(0.0f)); // y < 0
@@ -1617,9 +1616,9 @@
face[3] = (face[0] >> 12) & 0x7;
face[0] &= 0x7;
- Float4 M = Max(Max(absX, absY), absZ);
+ M = Max(Max(absX, absY), absZ);
- // U = xMajor ? (neg ^ -z) : (zMajor & neg) ^ x)
+ // U = xMajor ? (neg ^ -z) : ((zMajor & neg) ^ x)
U = As<Float4>((xMajor & (n ^ As<Int4>(-z))) | (~xMajor & ((zMajor & n) ^ As<Int4>(x))));
// V = !yMajor ? -y : (n ^ z)
@@ -1628,10 +1627,6 @@
M = reciprocal(M) * Float4(0.5f);
U = U * M + Float4(0.5f);
V = V * M + Float4(0.5f);
-
- lodX = x * M;
- lodY = y * M;
- lodZ = z * M;
}
Short4 SamplerCore::applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode)
@@ -1639,7 +1634,7 @@
Int4 tmp = Int4(As<UShort4>(uvw));
tmp = tmp + As<Int4>(offset);
- switch (mode)
+ switch(mode)
{
case AddressingMode::ADDRESSING_WRAP:
tmp = (tmp + whd * Int4(-MIN_PROGRAM_TEXEL_OFFSET)) % whd;
@@ -1652,6 +1647,8 @@
break;
case ADDRESSING_TEXELFETCH:
break;
+ case AddressingMode::ADDRESSING_SEAMLESS:
+ ASSERT(false); // Cube sampling doesn't support offset.
default:
ASSERT(false);
}
@@ -1672,8 +1669,10 @@
if(hasOffset)
{
- uuuu = applyOffset(uuuu, offset.x, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, width))), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeU);
- vvvv = applyOffset(vvvv, offset.y, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, height))), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeV);
+ UShort4 w = *Pointer<UShort4>(mipmap + OFFSET(Mipmap, width));
+ uuuu = applyOffset(uuuu, offset.x, Int4(w), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeU);
+ UShort4 h = *Pointer<UShort4>(mipmap + OFFSET(Mipmap, height));
+ vvvv = applyOffset(vvvv, offset.y, Int4(h), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeV);
}
Short4 uuu2 = uuuu;
@@ -1690,24 +1689,29 @@
{
wwww = MulHigh(As<UShort4>(wwww), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth)));
}
+
if(hasOffset)
{
- wwww = applyOffset(wwww, offset.z, Int4(*Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth))), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeW);
+ UShort4 d = *Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth));
+ wwww = applyOffset(wwww, offset.z, Int4(d), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeW);
}
}
- Short4 www2 = wwww;
- wwww = As<Short4>(UnpackLow(wwww, Short4(0x0000)));
- www2 = As<Short4>(UnpackHigh(www2, Short4(0x0000)));
- wwww = As<Short4>(MulAdd(wwww, *Pointer<Short4>(mipmap + OFFSET(Mipmap,sliceP))));
- www2 = As<Short4>(MulAdd(www2, *Pointer<Short4>(mipmap + OFFSET(Mipmap,sliceP))));
- uuuu = As<Short4>(As<Int2>(uuuu) + As<Int2>(wwww));
- uuu2 = As<Short4>(As<Int2>(uuu2) + As<Int2>(www2));
- }
- index[0] = Extract(As<Int2>(uuuu), 0);
- index[1] = Extract(As<Int2>(uuuu), 1);
- index[2] = Extract(As<Int2>(uuu2), 0);
- index[3] = Extract(As<Int2>(uuu2), 1);
+ UInt4 uv(As<UInt2>(uuuu), As<UInt2>(uuu2));
+ uv += As<UInt4>(Int4(As<UShort4>(wwww))) * *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sliceP));
+
+ index[0] = Extract(As<Int4>(uv), 0);
+ index[1] = Extract(As<Int4>(uv), 1);
+ index[2] = Extract(As<Int4>(uv), 2);
+ index[3] = Extract(As<Int4>(uv), 3);
+ }
+ else
+ {
+ index[0] = Extract(As<Int2>(uuuu), 0);
+ index[1] = Extract(As<Int2>(uuuu), 1);
+ index[2] = Extract(As<Int2>(uuu2), 0);
+ index[3] = Extract(As<Int2>(uuu2), 1);
+ }
if(texelFetch)
{
@@ -1795,7 +1799,7 @@
break;
case FORMAT_A8B8G8R8:
case FORMAT_A8B8G8R8I:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_Q8W8V8U8:
case FORMAT_SRGB8_A8:
c.z = As<Short4>(UnpackHigh(c.x, c.y));
@@ -1849,7 +1853,7 @@
c.y = UnpackHigh(As<Byte8>(c.y), As<Byte8>(c.y));
c.x = UnpackLow(As<Byte8>(c.x), As<Byte8>(c.x));
break;
- case FORMAT_X8B8G8R8I_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
case FORMAT_X8B8G8R8I:
case FORMAT_X8B8G8R8:
case FORMAT_X8L8V8U8:
@@ -1890,7 +1894,7 @@
switch(state.textureFormat)
{
case FORMAT_G8R8:
- case FORMAT_G8R8I_SNORM:
+ case FORMAT_G8R8_SNORM:
case FORMAT_V8U8:
case FORMAT_A8L8:
c.y = (c.x & Short4(0xFF00u)) | As<Short4>(As<UShort4>(c.x) >> 8);
@@ -1951,6 +1955,13 @@
c.w = Pointer<Short4>(buffer[f3])[index[3]];
transpose4x4(c.x, c.y, c.z, c.w);
break;
+ case 3:
+ c.x = Pointer<Short4>(buffer[f0])[index[0]];
+ c.y = Pointer<Short4>(buffer[f1])[index[1]];
+ c.z = Pointer<Short4>(buffer[f2])[index[2]];
+ c.w = Pointer<Short4>(buffer[f3])[index[3]];
+ transpose4x3(c.x, c.y, c.z, c.w);
+ break;
case 2:
c.x = *Pointer<Short4>(buffer[f0] + 4 * index[0]);
c.x = As<Short4>(UnpackLow(c.x, *Pointer<Short4>(buffer[f1] + 4 * index[1])));
@@ -1972,6 +1983,26 @@
}
else ASSERT(false);
+ if(state.sRGB)
+ {
+ if(state.textureFormat == FORMAT_R5G6B5)
+ {
+ sRGBtoLinear16_5_16(c.x);
+ sRGBtoLinear16_6_16(c.y);
+ sRGBtoLinear16_5_16(c.z);
+ }
+ else
+ {
+ for(int i = 0; i < textureComponentCount(); i++)
+ {
+ if(isRGBComponent(i))
+ {
+ sRGBtoLinear16_8_16(c[i]);
+ }
+ }
+ }
+ }
+
return c;
}
@@ -2109,13 +2140,11 @@
transpose4x4(c.x, c.y, c.z, c.w);
break;
case 3:
- ASSERT(state.textureFormat == FORMAT_X32B32G32R32F);
c.x = *Pointer<Float4>(buffer[f0] + index[0] * 16, 16);
c.y = *Pointer<Float4>(buffer[f1] + index[1] * 16, 16);
c.z = *Pointer<Float4>(buffer[f2] + index[2] * 16, 16);
c.w = *Pointer<Float4>(buffer[f3] + index[3] * 16, 16);
transpose4x3(c.x, c.y, c.z, c.w);
- c.w = Float4(1.0f);
break;
case 2:
// FIXME: Optimal shuffling?
@@ -2133,17 +2162,40 @@
c.x.y = *Pointer<Float>(buffer[f1] + index[1] * 4);
c.x.z = *Pointer<Float>(buffer[f2] + index[2] * 4);
c.x.w = *Pointer<Float>(buffer[f3] + index[3] * 4);
-
- if(state.textureFormat == FORMAT_D32FS8_SHADOW && state.textureFilter != FILTER_GATHER)
- {
- Float4 d = Min(Max(z, Float4(0.0f)), Float4(1.0f));
-
- c.x = As<Float4>(As<Int4>(CmpNLT(c.x, d)) & As<Int4>(Float4(1.0f))); // FIXME: Only less-equal?
- }
break;
default:
ASSERT(false);
}
+
+ if(state.compare != COMPARE_BYPASS)
+ {
+ Float4 ref = z;
+
+ if(!hasFloatTexture())
+ {
+ ref = Min(Max(ref, Float4(0.0f)), Float4(1.0f));
+ }
+
+ Int4 boolean;
+
+ switch(state.compare)
+ {
+ case COMPARE_LESSEQUAL: boolean = CmpLE(ref, c.x); break;
+ case COMPARE_GREATEREQUAL: boolean = CmpNLT(ref, c.x); break;
+ case COMPARE_LESS: boolean = CmpLT(ref, c.x); break;
+ case COMPARE_GREATER: boolean = CmpNLE(ref, c.x); break;
+ case COMPARE_EQUAL: boolean = CmpEQ(ref, c.x); break;
+ case COMPARE_NOTEQUAL: boolean = CmpNEQ(ref, c.x); break;
+ case COMPARE_ALWAYS: boolean = Int4(-1); break;
+ case COMPARE_NEVER: boolean = Int4(0); break;
+ default: ASSERT(false);
+ }
+
+ c.x = As<Float4>(boolean & As<Int4>(Float4(1.0f)));
+ c.y = Float4(0.0f);
+ c.z = Float4(0.0f);
+ c.w = Float4(1.0f);
+ }
}
else
{
@@ -2153,7 +2205,7 @@
bool isInteger = Surface::isNonNormalizedInteger(state.textureFormat);
int componentCount = textureComponentCount();
- for(int n = 0; n < componentCount; ++n)
+ for(int n = 0; n < componentCount; n++)
{
if(hasUnsignedTextureComponent(n))
{
@@ -2185,7 +2237,7 @@
void SamplerCore::selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD)
{
- if(state.mipmapFilter < MIPMAP_POINT)
+ if(state.mipmapFilter == MIPMAP_NONE)
{
mipmap = texture + OFFSET(Texture,mipmap[0]);
}
@@ -2197,7 +2249,7 @@
{
ilod = RoundInt(lod);
}
- else // Linear
+ else // MIPMAP_LINEAR
{
ilod = Int(lod);
}
@@ -2226,20 +2278,25 @@
Int4 SamplerCore::computeFilterOffset(Float &lod)
{
- Int4 filtering((state.textureFilter == FILTER_POINT) ? 0 : 1);
- if(state.textureFilter == FILTER_MIN_LINEAR_MAG_POINT)
+ Int4 filter = -1;
+
+ if(state.textureFilter == FILTER_POINT)
{
- filtering &= CmpNLE(Float4(lod), Float4(0.0f));
+ filter = 0;
+ }
+ else if(state.textureFilter == FILTER_MIN_LINEAR_MAG_POINT)
+ {
+ filter = CmpNLE(Float4(lod), Float4(0.0f));
}
else if(state.textureFilter == FILTER_MIN_POINT_MAG_LINEAR)
{
- filtering &= CmpLE(Float4(lod), Float4(0.0f));
+ filter = CmpLE(Float4(lod), Float4(0.0f));
}
- return filtering;
+ return filter;
}
- Short4 SamplerCore::address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap)
+ Short4 SamplerCore::address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte> &mipmap)
{
if(addressingMode == ADDRESSING_LAYER && state.textureType != TEXTURE_2D_ARRAY)
{
@@ -2249,7 +2306,7 @@
{
return Min(Max(Short4(RoundInt(uw)), Short4(0)), *Pointer<Short4>(mipmap + OFFSET(Mipmap, depth)) - Short4(1));
}
- else if(addressingMode == ADDRESSING_CLAMP)
+ else if(addressingMode == ADDRESSING_CLAMP || addressingMode == ADDRESSING_BORDER)
{
Float4 clamp = Min(Max(uw, Float4(0.0f)), Float4(65535.0f / 65536.0f));
@@ -2271,21 +2328,21 @@
// Clamp
convert -= Int4(0x00008000, 0x00008000, 0x00008000, 0x00008000);
- convert = As<Int4>(Pack(convert, convert));
+ convert = As<Int4>(PackSigned(convert, convert));
return As<Short4>(Int2(convert)) + Short4(0x8000u);
}
- else // Wrap (or border)
+ else // Wrap
{
return Short4(Int4(uw * Float4(1 << 16)));
}
}
- void SamplerCore::address(Float4 &uvw, Int4& xyz0, Int4& xyz1, Float4& f, Pointer<Byte>& mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function)
+ void SamplerCore::address(Float4 &uvw, Int4 &xyz0, Int4 &xyz1, Float4 &f, Pointer<Byte> &mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function)
{
if(addressingMode == ADDRESSING_LAYER && state.textureType != TEXTURE_2D_ARRAY)
{
- return; // Unused
+ return; // Unused
}
Int4 dim = Int4(*Pointer<Short4>(mipmap + whd, 16));
@@ -2295,98 +2352,140 @@
{
xyz0 = Min(Max(((function.option == Offset) && (addressingMode != ADDRESSING_LAYER)) ? As<Int4>(uvw) + As<Int4>(texOffset) : As<Int4>(uvw), Int4(0)), maxXYZ);
}
- else if(addressingMode == ADDRESSING_LAYER && state.textureType == TEXTURE_2D_ARRAY) // Note: Offset does not apply to array layers
+ else if(addressingMode == ADDRESSING_LAYER && state.textureType == TEXTURE_2D_ARRAY) // Note: Offset does not apply to array layers
{
xyz0 = Min(Max(RoundInt(uvw), Int4(0)), maxXYZ);
}
else
{
- const int halfBits = 0x3effffff; // Value just under 0.5f
- const int oneBits = 0x3f7fffff; // Value just under 1.0f
- const int twoBits = 0x3fffffff; // Value just under 2.0f
+ const int halfBits = 0x3EFFFFFF; // Value just under 0.5f
+ const int oneBits = 0x3F7FFFFF; // Value just under 1.0f
+ const int twoBits = 0x3FFFFFFF; // Value just under 2.0f
- Float4 coord = Float4(dim);
- switch(addressingMode)
+ bool pointFilter = state.textureFilter == FILTER_POINT ||
+ state.textureFilter == FILTER_MIN_POINT_MAG_LINEAR ||
+ state.textureFilter == FILTER_MIN_LINEAR_MAG_POINT;
+
+ Float4 coord = uvw;
+
+ if(state.textureType == TEXTURE_RECTANGLE)
{
- case ADDRESSING_CLAMP:
+ coord = Min(Max(coord, Float4(0.0f)), Float4(dim - Int4(1)));
+ }
+ else
+ {
+ switch(addressingMode)
{
- Float4 one = As<Float4>(Int4(oneBits));
- coord *= Min(Max(uvw, Float4(0.0f)), one);
- }
- break;
- case ADDRESSING_MIRROR:
+ case ADDRESSING_CLAMP:
+ case ADDRESSING_BORDER:
+ case ADDRESSING_SEAMLESS:
+ // Linear filtering of cube doesn't require clamping because the coordinates
+ // are already in [0, 1] range and numerical imprecision is tolerated.
+ if(addressingMode != ADDRESSING_SEAMLESS || pointFilter)
+ {
+ Float4 one = As<Float4>(Int4(oneBits));
+ coord = Min(Max(coord, Float4(0.0f)), one);
+ }
+ break;
+ case ADDRESSING_MIRROR:
{
Float4 half = As<Float4>(Int4(halfBits));
Float4 one = As<Float4>(Int4(oneBits));
Float4 two = As<Float4>(Int4(twoBits));
- coord *= one - Abs(two * Frac(uvw * half) - one);
+ coord = one - Abs(two * Frac(coord * half) - one);
}
break;
- case ADDRESSING_MIRRORONCE:
+ case ADDRESSING_MIRRORONCE:
{
Float4 half = As<Float4>(Int4(halfBits));
Float4 one = As<Float4>(Int4(oneBits));
Float4 two = As<Float4>(Int4(twoBits));
- coord *= one - Abs(two * Frac(Min(Max(uvw, -one), two) * half) - one);
+ coord = one - Abs(two * Frac(Min(Max(coord, -one), two) * half) - one);
}
break;
- default: // Wrap (or border)
- coord *= Frac(uvw);
- break;
+ default: // Wrap
+ coord = Frac(coord);
+ break;
+ }
+
+ coord = coord * Float4(dim);
}
- xyz0 = Int4(coord);
+ if(state.textureFilter == FILTER_POINT ||
+ state.textureFilter == FILTER_GATHER)
+ {
+ xyz0 = Int4(coord);
+ }
+ else
+ {
+ if(state.textureFilter == FILTER_MIN_POINT_MAG_LINEAR ||
+ state.textureFilter == FILTER_MIN_LINEAR_MAG_POINT)
+ {
+ coord -= As<Float4>(As<Int4>(Float4(0.5f)) & filter);
+ }
+ else
+ {
+ coord -= Float4(0.5f);
+ }
+
+ Float4 floor = Floor(coord);
+ xyz0 = Int4(floor);
+ f = coord - floor;
+ }
if(function.option == Offset)
{
xyz0 += As<Int4>(texOffset);
+ }
+
+ if(addressingMode == ADDRESSING_SEAMLESS)
+ {
+ xyz0 += Int4(1);
+ }
+
+ xyz1 = xyz0 - filter; // Increment
+
+ if(function.option == Offset)
+ {
switch(addressingMode)
{
+ case ADDRESSING_SEAMLESS:
+ ASSERT(false); // Cube sampling doesn't support offset.
case ADDRESSING_MIRROR:
case ADDRESSING_MIRRORONCE:
case ADDRESSING_BORDER:
- // FIXME: Implement ADDRESSING_MIRROR, ADDRESSING_MIRRORONCE and ADDRESSING_BORDER. Fall through to Clamp.
+ // FIXME: Implement ADDRESSING_MIRROR, ADDRESSING_MIRRORONCE, and ADDRESSING_BORDER.
+ // Fall through to Clamp.
case ADDRESSING_CLAMP:
xyz0 = Min(Max(xyz0, Int4(0)), maxXYZ);
+ xyz1 = Min(Max(xyz1, Int4(0)), maxXYZ);
break;
default: // Wrap
xyz0 = (xyz0 + dim * Int4(-MIN_PROGRAM_TEXEL_OFFSET)) % dim;
+ xyz1 = (xyz1 + dim * Int4(-MIN_PROGRAM_TEXEL_OFFSET)) % dim;
break;
}
}
-
- if(state.textureFilter != FILTER_POINT) // Compute 2nd coordinate, if needed
+ else if(state.textureFilter != FILTER_POINT)
{
- bool gather = state.textureFilter == FILTER_GATHER;
-
- xyz1 = xyz0 + filter; // Increment
-
- if(!gather)
- {
- Float4 frac = Frac(coord);
- f = Abs(frac - Float4(0.5f));
- xyz1 -= CmpLT(frac, Float4(0.5f)) & (filter + filter); // Decrement xyz if necessary
- }
-
switch(addressingMode)
{
+ case ADDRESSING_SEAMLESS:
+ break;
case ADDRESSING_MIRROR:
case ADDRESSING_MIRRORONCE:
case ADDRESSING_BORDER:
- // FIXME: Implement ADDRESSING_MIRROR, ADDRESSING_MIRRORONCE and ADDRESSING_BORDER. Fall through to Clamp.
case ADDRESSING_CLAMP:
- xyz1 = gather ? Min(xyz1, maxXYZ) : Min(Max(xyz1, Int4(0)), maxXYZ);
+ xyz0 = Max(xyz0, Int4(0));
+ xyz1 = Min(xyz1, maxXYZ);
break;
default: // Wrap
{
- // The coordinates overflow or underflow by at most 1
- Int4 over = CmpNLT(xyz1, dim);
- xyz1 = (over & Int4(0)) | (~over & xyz1); // xyz >= dim ? 0 : xyz
- if(!gather)
- {
- Int4 under = CmpLT(xyz1, Int4(0));
- xyz1 = (under & maxXYZ) | (~under & xyz1); // xyz < 0 ? dim - 1 : xyz
- }
+ Int4 under = CmpLT(xyz0, Int4(0));
+ xyz0 = (under & maxXYZ) | (~under & xyz0); // xyz < 0 ? dim - 1 : xyz // FIXME: IfThenElse()
+
+ Int4 nover = CmpLT(xyz1, dim);
+ xyz1 = nover & xyz1; // xyz >= dim ? 0 : xyz
}
break;
}
@@ -2430,11 +2529,11 @@
cf = Float4(As<UShort4>(cs)) * Float4(1.0f / 0xFFFF);
}
- void SamplerCore::sRGBtoLinear16_8_12(Short4 &c)
+ void SamplerCore::sRGBtoLinear16_8_16(Short4 &c)
{
c = As<UShort4>(c) >> 8;
- Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear8_12));
+ Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear8_16));
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
@@ -2442,11 +2541,11 @@
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 3))), 3);
}
- void SamplerCore::sRGBtoLinear16_6_12(Short4 &c)
+ void SamplerCore::sRGBtoLinear16_6_16(Short4 &c)
{
c = As<UShort4>(c) >> 10;
- Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear6_12));
+ Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear6_16));
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
@@ -2454,11 +2553,11 @@
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 3))), 3);
}
- void SamplerCore::sRGBtoLinear16_5_12(Short4 &c)
+ void SamplerCore::sRGBtoLinear16_5_16(Short4 &c)
{
c = As<UShort4>(c) >> 11;
- Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear5_12));
+ Pointer<Byte> LUT = Pointer<Byte>(constants + OFFSET(Constants,sRGBtoLinear5_16));
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 0))), 0);
c = Insert(c, *Pointer<Short>(LUT + 2 * Int(Extract(c, 1))), 1);
@@ -2497,10 +2596,10 @@
{
case FORMAT_R5G6B5:
return true;
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_R8I:
case FORMAT_R8UI:
case FORMAT_G8R8I:
@@ -2531,13 +2630,16 @@
case FORMAT_G32R32F:
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_A8:
case FORMAT_R8:
case FORMAT_L8:
case FORMAT_A8L8:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_L16:
case FORMAT_G16R16:
@@ -2582,10 +2684,10 @@
case FORMAT_R8:
case FORMAT_L8:
case FORMAT_A8L8:
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_R8I:
case FORMAT_R8UI:
case FORMAT_G8R8I:
@@ -2600,9 +2702,12 @@
case FORMAT_G32R32F:
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_L16:
case FORMAT_G16R16:
@@ -2642,10 +2747,10 @@
switch(state.textureFormat)
{
case FORMAT_R5G6B5:
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_R8I:
case FORMAT_R8UI:
case FORMAT_G8R8I:
@@ -2676,13 +2781,16 @@
case FORMAT_G32R32F:
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_A8:
case FORMAT_R8:
case FORMAT_L8:
case FORMAT_A8L8:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_YV12_BT601:
case FORMAT_YV12_BT709:
@@ -2715,10 +2823,10 @@
switch(state.textureFormat)
{
case FORMAT_R5G6B5:
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_R8I:
case FORMAT_R8UI:
case FORMAT_G8R8I:
@@ -2755,13 +2863,16 @@
case FORMAT_G32R32F:
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_A8:
case FORMAT_R8:
case FORMAT_L8:
case FORMAT_A8L8:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_YV12_BT601:
case FORMAT_YV12_BT709:
@@ -2792,10 +2903,10 @@
case FORMAT_YV12_JFIF:
return true;
case FORMAT_R5G6B5:
- case FORMAT_R8I_SNORM:
- case FORMAT_G8R8I_SNORM:
- case FORMAT_X8B8G8R8I_SNORM:
- case FORMAT_A8B8G8R8I_SNORM:
+ case FORMAT_R8_SNORM:
+ case FORMAT_G8R8_SNORM:
+ case FORMAT_X8B8G8R8_SNORM:
+ case FORMAT_A8B8G8R8_SNORM:
case FORMAT_R8I:
case FORMAT_R8UI:
case FORMAT_G8R8I:
@@ -2826,13 +2937,16 @@
case FORMAT_G32R32F:
case FORMAT_X32B32G32R32F:
case FORMAT_A32B32G32R32F:
+ case FORMAT_X32B32G32R32F_UNSIGNED:
case FORMAT_A8:
case FORMAT_R8:
case FORMAT_L8:
case FORMAT_A8L8:
case FORMAT_D32F:
+ case FORMAT_D32FS8:
case FORMAT_D32F_LOCKABLE:
case FORMAT_D32FS8_TEXTURE:
+ case FORMAT_D32F_SHADOW:
case FORMAT_D32FS8_SHADOW:
case FORMAT_L16:
case FORMAT_G16R16:
@@ -2861,10 +2975,10 @@
switch(state.textureFormat)
{
case FORMAT_R5G6B5: return component < 3;
- case FORMAT_R8I_SNORM: return component < 1;
- case FORMAT_G8R8I_SNORM: return component < 2;
- case FORMAT_X8B8G8R8I_SNORM: return component < 3;
- case FORMAT_A8B8G8R8I_SNORM: return component < 3;
+ case FORMAT_R8_SNORM: return component < 1;
+ case FORMAT_G8R8_SNORM: return component < 2;
+ case FORMAT_X8B8G8R8_SNORM: return component < 3;
+ case FORMAT_A8B8G8R8_SNORM: return component < 3;
case FORMAT_R8I: return component < 1;
case FORMAT_R8UI: return component < 1;
case FORMAT_G8R8I: return component < 2;
@@ -2895,13 +3009,16 @@
case FORMAT_G32R32F: return component < 2;
case FORMAT_X32B32G32R32F: return component < 3;
case FORMAT_A32B32G32R32F: return component < 3;
+ case FORMAT_X32B32G32R32F_UNSIGNED: return component < 3;
case FORMAT_A8: return false;
case FORMAT_R8: return component < 1;
case FORMAT_L8: return component < 1;
case FORMAT_A8L8: return component < 1;
case FORMAT_D32F: return false;
+ case FORMAT_D32FS8: return false;
case FORMAT_D32F_LOCKABLE: return false;
case FORMAT_D32FS8_TEXTURE: return false;
+ case FORMAT_D32F_SHADOW: return false;
case FORMAT_D32FS8_SHADOW: return false;
case FORMAT_L16: return component < 1;
case FORMAT_G16R16: return component < 2;
diff --git a/src/Shader/SamplerCore.hpp b/src/Shader/SamplerCore.hpp
index 9f8e85b..684c1a7 100644
--- a/src/Shader/SamplerCore.hpp
+++ b/src/Shader/SamplerCore.hpp
@@ -22,17 +22,18 @@
{
enum SamplerMethod
{
- Implicit,
- Bias,
- Lod,
- Grad,
- Fetch
+ Implicit, // Compute gradients (pixel shader only).
+ Bias, // Compute gradients and add provided bias.
+ Lod, // Use provided LOD.
+ Grad, // Use provided gradients.
+ Fetch, // Use provided integer coordinates.
+ Base // Sample base level.
};
enum SamplerOption
{
None,
- Offset
+ Offset // Offset sample location by provided integer coordinates.
};
struct SamplerFunction
@@ -47,38 +48,38 @@
class SamplerCore
{
public:
- SamplerCore(Pointer<Byte> &r, const Sampler::State &state);
+ SamplerCore(Pointer<Byte> &constants, const Sampler::State &state);
- void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy);
- void sampleTexture(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
- void textureSize(Pointer<Byte> &mipmap, Vector4f &size, Float4 &lod);
+ Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy);
+ Vector4f sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
+ static Vector4f textureSize(Pointer<Byte> &mipmap, Float4 &lod);
private:
- void sampleTexture(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function, bool fixed12);
+ Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function, bool fixed12);
void border(Short4 &mask, Float4 &coordinates);
void border(Int4 &mask, Float4 &coordinates);
Short4 offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);
- void sampleFilter(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
- void sampleAniso(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
- void sampleQuad(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
- void sampleQuad2D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
- void sample3D(Pointer<Byte> &texture, Vector4s &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
- void sampleFloatFilter(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
- void sampleFloatAniso(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
- void sampleFloat(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
- void sampleFloat2D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
- void sampleFloat3D(Pointer<Byte> &texture, Vector4f &c, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
+ Vector4s sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
+ Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
+ Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
+ Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
+ Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
+ Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
+ Vector4f sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
+ Vector4f sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
+ Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function);
+ Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Float log2sqrt(Float lod);
+ Float log2(Float lod);
void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
- void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &x, Float4 &y, Float4 &z, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
+ void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function);
void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
- void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &lodX, Float4 &lodY, Float4 &lodZ, Float4 &x, Float4 &y, Float4 &z);
+ void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M);
Short4 applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode);
void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, SamplerFunction function);
void computeIndices(UInt index[4], Int4& uuuu, Int4& vvvv, Int4& wwww, const Pointer<Byte> &mipmap, SamplerFunction function);
Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function);
- Vector4f sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function);
Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer[4]);
Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &s, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function);
void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD);
@@ -91,9 +92,9 @@
void convertSigned12(Float4 &cf, Short4 &ci);
void convertSigned15(Float4 &cf, Short4 &ci);
void convertUnsigned16(Float4 &cf, Short4 &ci);
- void sRGBtoLinear16_8_12(Short4 &c);
- void sRGBtoLinear16_6_12(Short4 &c);
- void sRGBtoLinear16_5_12(Short4 &c);
+ void sRGBtoLinear16_8_16(Short4 &c);
+ void sRGBtoLinear16_6_16(Short4 &c);
+ void sRGBtoLinear16_5_16(Short4 &c);
bool hasFloatTexture() const;
bool hasUnnormalizedIntegerTexture() const;
diff --git a/src/Shader/SetupRoutine.cpp b/src/Shader/SetupRoutine.cpp
index 2fd1883..d733c2d 100644
--- a/src/Shader/SetupRoutine.cpp
+++ b/src/Shader/SetupRoutine.cpp
@@ -224,7 +224,9 @@
if(state.multiSample > 1)
{
- Short x = Short((X[0] + 0xF) >> 4);
+ Int xMin = *Pointer<Int>(data + OFFSET(DrawData, scissorX0));
+ Int xMax = *Pointer<Int>(data + OFFSET(DrawData, scissorX1));
+ Short x = Short(Clamp((X[0] + 0xF) >> 4, xMin, xMax));
For(Int y = yMin - 1, y < yMax + 1, y++)
{
diff --git a/src/Shader/SetupRoutine.hpp b/src/Shader/SetupRoutine.hpp
index ebcc080..c1c3205 100644
--- a/src/Shader/SetupRoutine.hpp
+++ b/src/Shader/SetupRoutine.hpp
@@ -15,7 +15,7 @@
#ifndef sw_SetupRoutine_hpp
#define sw_SetupRoutine_hpp
-#include "SetupProcessor.hpp"
+#include "Renderer/SetupProcessor.hpp"
#include "Reactor/Reactor.hpp"
namespace sw
diff --git a/src/Shader/Shader.cpp b/src/Shader/Shader.cpp
index ff1482e..025b5d5 100644
--- a/src/Shader/Shader.cpp
+++ b/src/Shader/Shader.cpp
@@ -16,8 +16,8 @@
#include "VertexShader.hpp"
#include "PixelShader.hpp"
-#include "Math.hpp"
-#include "Debug.hpp"
+#include "Common/Math.hpp"
+#include "Common/Debug.hpp"
#include <set>
#include <fstream>
@@ -317,11 +317,6 @@
std::string modifierString;
- if(integer)
- {
- modifierString += "_int";
- }
-
if(saturate)
{
modifierString += "_sat";
@@ -508,6 +503,24 @@
return "";
}
+ std::string Shader::SourceParameter::string(ShaderType shaderType, unsigned short version) const
+ {
+ if(type == PARAMETER_CONST && bufferIndex >= 0)
+ {
+ std::ostringstream buffer;
+ buffer << bufferIndex;
+
+ std::ostringstream offset;
+ offset << index;
+
+ return "cb" + buffer.str() + "[" + offset.str() + "]";
+ }
+ else
+ {
+ return Parameter::string(shaderType, version);
+ }
+ }
+
std::string Shader::SourceParameter::swizzleString() const
{
return Instruction::swizzleString(type, swizzle);
@@ -747,232 +760,234 @@
{
switch(opcode)
{
- case OPCODE_NULL: return "null";
- case OPCODE_NOP: return "nop";
- case OPCODE_MOV: return "mov";
- case OPCODE_ADD: return "add";
- case OPCODE_IADD: return "iadd";
- case OPCODE_SUB: return "sub";
- case OPCODE_ISUB: return "isub";
- case OPCODE_MAD: return "mad";
- case OPCODE_IMAD: return "imad";
- case OPCODE_MUL: return "mul";
- case OPCODE_IMUL: return "imul";
- case OPCODE_RCPX: return "rcpx";
- case OPCODE_DIV: return "div";
- case OPCODE_IDIV: return "idiv";
- case OPCODE_UDIV: return "udiv";
- case OPCODE_MOD: return "mod";
- case OPCODE_IMOD: return "imod";
- case OPCODE_UMOD: return "umod";
- case OPCODE_SHL: return "shl";
- case OPCODE_ISHR: return "ishr";
- case OPCODE_USHR: return "ushr";
- case OPCODE_RSQX: return "rsqx";
- case OPCODE_SQRT: return "sqrt";
- case OPCODE_RSQ: return "rsq";
- case OPCODE_LEN2: return "len2";
- case OPCODE_LEN3: return "len3";
- case OPCODE_LEN4: return "len4";
- case OPCODE_DIST1: return "dist1";
- case OPCODE_DIST2: return "dist2";
- case OPCODE_DIST3: return "dist3";
- case OPCODE_DIST4: return "dist4";
- case OPCODE_DP3: return "dp3";
- case OPCODE_DP4: return "dp4";
- case OPCODE_DET2: return "det2";
- case OPCODE_DET3: return "det3";
- case OPCODE_DET4: return "det4";
- case OPCODE_MIN: return "min";
- case OPCODE_IMIN: return "imin";
- case OPCODE_UMIN: return "umin";
- case OPCODE_MAX: return "max";
- case OPCODE_IMAX: return "imax";
- case OPCODE_UMAX: return "umax";
- case OPCODE_SLT: return "slt";
- case OPCODE_SGE: return "sge";
- case OPCODE_EXP2X: return "exp2x";
- case OPCODE_LOG2X: return "log2x";
- case OPCODE_LIT: return "lit";
- case OPCODE_ATT: return "att";
- case OPCODE_LRP: return "lrp";
- case OPCODE_STEP: return "step";
- case OPCODE_SMOOTH: return "smooth";
- case OPCODE_FLOATBITSTOINT: return "floatBitsToInt";
+ case OPCODE_NULL: return "null";
+ case OPCODE_NOP: return "nop";
+ case OPCODE_MOV: return "mov";
+ case OPCODE_ADD: return "add";
+ case OPCODE_IADD: return "iadd";
+ case OPCODE_SUB: return "sub";
+ case OPCODE_ISUB: return "isub";
+ case OPCODE_MAD: return "mad";
+ case OPCODE_IMAD: return "imad";
+ case OPCODE_MUL: return "mul";
+ case OPCODE_IMUL: return "imul";
+ case OPCODE_RCPX: return "rcpx";
+ case OPCODE_DIV: return "div";
+ case OPCODE_IDIV: return "idiv";
+ case OPCODE_UDIV: return "udiv";
+ case OPCODE_MOD: return "mod";
+ case OPCODE_IMOD: return "imod";
+ case OPCODE_UMOD: return "umod";
+ case OPCODE_SHL: return "shl";
+ case OPCODE_ISHR: return "ishr";
+ case OPCODE_USHR: return "ushr";
+ case OPCODE_RSQX: return "rsqx";
+ case OPCODE_SQRT: return "sqrt";
+ case OPCODE_RSQ: return "rsq";
+ case OPCODE_LEN2: return "len2";
+ case OPCODE_LEN3: return "len3";
+ case OPCODE_LEN4: return "len4";
+ case OPCODE_DIST1: return "dist1";
+ case OPCODE_DIST2: return "dist2";
+ case OPCODE_DIST3: return "dist3";
+ case OPCODE_DIST4: return "dist4";
+ case OPCODE_DP3: return "dp3";
+ case OPCODE_DP4: return "dp4";
+ case OPCODE_DET2: return "det2";
+ case OPCODE_DET3: return "det3";
+ case OPCODE_DET4: return "det4";
+ case OPCODE_MIN: return "min";
+ case OPCODE_IMIN: return "imin";
+ case OPCODE_UMIN: return "umin";
+ case OPCODE_MAX: return "max";
+ case OPCODE_IMAX: return "imax";
+ case OPCODE_UMAX: return "umax";
+ case OPCODE_SLT: return "slt";
+ case OPCODE_SGE: return "sge";
+ case OPCODE_EXP2X: return "exp2x";
+ case OPCODE_LOG2X: return "log2x";
+ case OPCODE_LIT: return "lit";
+ case OPCODE_ATT: return "att";
+ case OPCODE_LRP: return "lrp";
+ case OPCODE_STEP: return "step";
+ case OPCODE_SMOOTH: return "smooth";
+ case OPCODE_FLOATBITSTOINT: return "floatBitsToInt";
case OPCODE_FLOATBITSTOUINT: return "floatBitsToUInt";
- case OPCODE_INTBITSTOFLOAT: return "intBitsToFloat";
+ case OPCODE_INTBITSTOFLOAT: return "intBitsToFloat";
case OPCODE_UINTBITSTOFLOAT: return "uintBitsToFloat";
- case OPCODE_PACKSNORM2x16: return "packSnorm2x16";
- case OPCODE_PACKUNORM2x16: return "packUnorm2x16";
- case OPCODE_PACKHALF2x16: return "packHalf2x16";
+ case OPCODE_PACKSNORM2x16: return "packSnorm2x16";
+ case OPCODE_PACKUNORM2x16: return "packUnorm2x16";
+ case OPCODE_PACKHALF2x16: return "packHalf2x16";
case OPCODE_UNPACKSNORM2x16: return "unpackSnorm2x16";
case OPCODE_UNPACKUNORM2x16: return "unpackUnorm2x16";
- case OPCODE_UNPACKHALF2x16: return "unpackHalf2x16";
- case OPCODE_FRC: return "frc";
- case OPCODE_M4X4: return "m4x4";
- case OPCODE_M4X3: return "m4x3";
- case OPCODE_M3X4: return "m3x4";
- case OPCODE_M3X3: return "m3x3";
- case OPCODE_M3X2: return "m3x2";
- case OPCODE_CALL: return "call";
- case OPCODE_CALLNZ: return "callnz";
- case OPCODE_LOOP: return "loop";
- case OPCODE_RET: return "ret";
- case OPCODE_ENDLOOP: return "endloop";
- case OPCODE_LABEL: return "label";
- case OPCODE_DCL: return "dcl";
- case OPCODE_POWX: return "powx";
- case OPCODE_CRS: return "crs";
- case OPCODE_SGN: return "sgn";
- case OPCODE_ISGN: return "isgn";
- case OPCODE_ABS: return "abs";
- case OPCODE_IABS: return "iabs";
- case OPCODE_NRM2: return "nrm2";
- case OPCODE_NRM3: return "nrm3";
- case OPCODE_NRM4: return "nrm4";
- case OPCODE_SINCOS: return "sincos";
- case OPCODE_REP: return "rep";
- case OPCODE_ENDREP: return "endrep";
- case OPCODE_IF: return "if";
- case OPCODE_IFC: return "ifc";
- case OPCODE_ELSE: return "else";
- case OPCODE_ENDIF: return "endif";
- case OPCODE_BREAK: return "break";
- case OPCODE_BREAKC: return "breakc";
- case OPCODE_MOVA: return "mova";
- case OPCODE_DEFB: return "defb";
- case OPCODE_DEFI: return "defi";
- case OPCODE_TEXCOORD: return "texcoord";
- case OPCODE_TEXKILL: return "texkill";
- case OPCODE_DISCARD: return "discard";
+ case OPCODE_UNPACKHALF2x16: return "unpackHalf2x16";
+ case OPCODE_FRC: return "frc";
+ case OPCODE_M4X4: return "m4x4";
+ case OPCODE_M4X3: return "m4x3";
+ case OPCODE_M3X4: return "m3x4";
+ case OPCODE_M3X3: return "m3x3";
+ case OPCODE_M3X2: return "m3x2";
+ case OPCODE_CALL: return "call";
+ case OPCODE_CALLNZ: return "callnz";
+ case OPCODE_LOOP: return "loop";
+ case OPCODE_RET: return "ret";
+ case OPCODE_ENDLOOP: return "endloop";
+ case OPCODE_LABEL: return "label";
+ case OPCODE_DCL: return "dcl";
+ case OPCODE_POWX: return "powx";
+ case OPCODE_CRS: return "crs";
+ case OPCODE_SGN: return "sgn";
+ case OPCODE_ISGN: return "isgn";
+ case OPCODE_ABS: return "abs";
+ case OPCODE_IABS: return "iabs";
+ case OPCODE_NRM2: return "nrm2";
+ case OPCODE_NRM3: return "nrm3";
+ case OPCODE_NRM4: return "nrm4";
+ case OPCODE_SINCOS: return "sincos";
+ case OPCODE_REP: return "rep";
+ case OPCODE_ENDREP: return "endrep";
+ case OPCODE_IF: return "if";
+ case OPCODE_IFC: return "ifc";
+ case OPCODE_ELSE: return "else";
+ case OPCODE_ENDIF: return "endif";
+ case OPCODE_BREAK: return "break";
+ case OPCODE_BREAKC: return "breakc";
+ case OPCODE_MOVA: return "mova";
+ case OPCODE_DEFB: return "defb";
+ case OPCODE_DEFI: return "defi";
+ case OPCODE_TEXCOORD: return "texcoord";
+ case OPCODE_TEXKILL: return "texkill";
+ case OPCODE_DISCARD: return "discard";
case OPCODE_TEX:
- if(version < 0x0104) return "tex";
- else return "texld";
- case OPCODE_TEXBEM: return "texbem";
- case OPCODE_TEXBEML: return "texbeml";
- case OPCODE_TEXREG2AR: return "texreg2ar";
- case OPCODE_TEXREG2GB: return "texreg2gb";
- case OPCODE_TEXM3X2PAD: return "texm3x2pad";
- case OPCODE_TEXM3X2TEX: return "texm3x2tex";
- case OPCODE_TEXM3X3PAD: return "texm3x3pad";
- case OPCODE_TEXM3X3TEX: return "texm3x3tex";
- case OPCODE_RESERVED0: return "reserved0";
- case OPCODE_TEXM3X3SPEC: return "texm3x3spec";
- case OPCODE_TEXM3X3VSPEC: return "texm3x3vspec";
- case OPCODE_EXPP: return "expp";
- case OPCODE_LOGP: return "logp";
- case OPCODE_CND: return "cnd";
- case OPCODE_DEF: return "def";
- case OPCODE_TEXREG2RGB: return "texreg2rgb";
- case OPCODE_TEXDP3TEX: return "texdp3tex";
- case OPCODE_TEXM3X2DEPTH: return "texm3x2depth";
- case OPCODE_TEXDP3: return "texdp3";
- case OPCODE_TEXM3X3: return "texm3x3";
- case OPCODE_TEXDEPTH: return "texdepth";
- case OPCODE_CMP0: return "cmp0";
- case OPCODE_ICMP: return "icmp";
- case OPCODE_UCMP: return "ucmp";
- case OPCODE_SELECT: return "select";
- case OPCODE_EXTRACT: return "extract";
- case OPCODE_INSERT: return "insert";
- case OPCODE_BEM: return "bem";
- case OPCODE_DP2ADD: return "dp2add";
- case OPCODE_DFDX: return "dFdx";
- case OPCODE_DFDY: return "dFdy";
- case OPCODE_FWIDTH: return "fwidth";
- case OPCODE_TEXLDD: return "texldd";
- case OPCODE_CMP: return "cmp";
- case OPCODE_TEXLDL: return "texldl";
- case OPCODE_TEXOFFSET: return "texoffset";
- case OPCODE_TEXLDLOFFSET: return "texldloffset";
- case OPCODE_TEXELFETCH: return "texelfetch";
+ if(version < 0x0104) return "tex";
+ else return "texld";
+ case OPCODE_TEXBEM: return "texbem";
+ case OPCODE_TEXBEML: return "texbeml";
+ case OPCODE_TEXREG2AR: return "texreg2ar";
+ case OPCODE_TEXREG2GB: return "texreg2gb";
+ case OPCODE_TEXM3X2PAD: return "texm3x2pad";
+ case OPCODE_TEXM3X2TEX: return "texm3x2tex";
+ case OPCODE_TEXM3X3PAD: return "texm3x3pad";
+ case OPCODE_TEXM3X3TEX: return "texm3x3tex";
+ case OPCODE_RESERVED0: return "reserved0";
+ case OPCODE_TEXM3X3SPEC: return "texm3x3spec";
+ case OPCODE_TEXM3X3VSPEC: return "texm3x3vspec";
+ case OPCODE_EXPP: return "expp";
+ case OPCODE_LOGP: return "logp";
+ case OPCODE_CND: return "cnd";
+ case OPCODE_DEF: return "def";
+ case OPCODE_TEXREG2RGB: return "texreg2rgb";
+ case OPCODE_TEXDP3TEX: return "texdp3tex";
+ case OPCODE_TEXM3X2DEPTH: return "texm3x2depth";
+ case OPCODE_TEXDP3: return "texdp3";
+ case OPCODE_TEXM3X3: return "texm3x3";
+ case OPCODE_TEXDEPTH: return "texdepth";
+ case OPCODE_CMP0: return "cmp0";
+ case OPCODE_ICMP: return "icmp";
+ case OPCODE_UCMP: return "ucmp";
+ case OPCODE_SELECT: return "select";
+ case OPCODE_EXTRACT: return "extract";
+ case OPCODE_INSERT: return "insert";
+ case OPCODE_BEM: return "bem";
+ case OPCODE_DP2ADD: return "dp2add";
+ case OPCODE_DFDX: return "dFdx";
+ case OPCODE_DFDY: return "dFdy";
+ case OPCODE_FWIDTH: return "fwidth";
+ case OPCODE_TEXLDD: return "texldd";
+ case OPCODE_CMP: return "cmp";
+ case OPCODE_TEXLDL: return "texldl";
+ case OPCODE_TEXBIAS: return "texbias";
+ case OPCODE_TEXOFFSET: return "texoffset";
+ case OPCODE_TEXOFFSETBIAS: return "texoffsetbias";
+ case OPCODE_TEXLODOFFSET: return "texlodoffset";
+ case OPCODE_TEXELFETCH: return "texelfetch";
case OPCODE_TEXELFETCHOFFSET: return "texelfetchoffset";
- case OPCODE_TEXGRAD: return "texgrad";
- case OPCODE_TEXGRADOFFSET: return "texgradoffset";
- case OPCODE_BREAKP: return "breakp";
- case OPCODE_TEXSIZE: return "texsize";
- case OPCODE_PHASE: return "phase";
- case OPCODE_COMMENT: return "comment";
- case OPCODE_END: return "end";
- case OPCODE_PS_1_0: return "ps_1_0";
- case OPCODE_PS_1_1: return "ps_1_1";
- case OPCODE_PS_1_2: return "ps_1_2";
- case OPCODE_PS_1_3: return "ps_1_3";
- case OPCODE_PS_1_4: return "ps_1_4";
- case OPCODE_PS_2_0: return "ps_2_0";
- case OPCODE_PS_2_x: return "ps_2_x";
- case OPCODE_PS_3_0: return "ps_3_0";
- case OPCODE_VS_1_0: return "vs_1_0";
- case OPCODE_VS_1_1: return "vs_1_1";
- case OPCODE_VS_2_0: return "vs_2_0";
- case OPCODE_VS_2_x: return "vs_2_x";
- case OPCODE_VS_2_sw: return "vs_2_sw";
- case OPCODE_VS_3_0: return "vs_3_0";
- case OPCODE_VS_3_sw: return "vs_3_sw";
- case OPCODE_WHILE: return "while";
- case OPCODE_ENDWHILE: return "endwhile";
- case OPCODE_COS: return "cos";
- case OPCODE_SIN: return "sin";
- case OPCODE_TAN: return "tan";
- case OPCODE_ACOS: return "acos";
- case OPCODE_ASIN: return "asin";
- case OPCODE_ATAN: return "atan";
- case OPCODE_ATAN2: return "atan2";
- case OPCODE_COSH: return "cosh";
- case OPCODE_SINH: return "sinh";
- case OPCODE_TANH: return "tanh";
- case OPCODE_ACOSH: return "acosh";
- case OPCODE_ASINH: return "asinh";
- case OPCODE_ATANH: return "atanh";
- case OPCODE_DP1: return "dp1";
- case OPCODE_DP2: return "dp2";
- case OPCODE_TRUNC: return "trunc";
- case OPCODE_FLOOR: return "floor";
- case OPCODE_ROUND: return "round";
- case OPCODE_ROUNDEVEN: return "roundEven";
- case OPCODE_CEIL: return "ceil";
- case OPCODE_EXP2: return "exp2";
- case OPCODE_LOG2: return "log2";
- case OPCODE_EXP: return "exp";
- case OPCODE_LOG: return "log";
- case OPCODE_POW: return "pow";
- case OPCODE_F2B: return "f2b";
- case OPCODE_B2F: return "b2f";
- case OPCODE_F2I: return "f2i";
- case OPCODE_I2F: return "i2f";
- case OPCODE_F2U: return "f2u";
- case OPCODE_U2F: return "u2f";
- case OPCODE_B2I: return "b2i";
- case OPCODE_I2B: return "i2b";
- case OPCODE_ALL: return "all";
- case OPCODE_ANY: return "any";
- case OPCODE_NEG: return "neg";
- case OPCODE_INEG: return "ineg";
- case OPCODE_ISNAN: return "isnan";
- case OPCODE_ISINF: return "isinf";
- case OPCODE_NOT: return "not";
- case OPCODE_OR: return "or";
- case OPCODE_XOR: return "xor";
- case OPCODE_AND: return "and";
- case OPCODE_EQ: return "eq";
- case OPCODE_NE: return "neq";
- case OPCODE_FORWARD1: return "forward1";
- case OPCODE_FORWARD2: return "forward2";
- case OPCODE_FORWARD3: return "forward3";
- case OPCODE_FORWARD4: return "forward4";
- case OPCODE_REFLECT1: return "reflect1";
- case OPCODE_REFLECT2: return "reflect2";
- case OPCODE_REFLECT3: return "reflect3";
- case OPCODE_REFLECT4: return "reflect4";
- case OPCODE_REFRACT1: return "refract1";
- case OPCODE_REFRACT2: return "refract2";
- case OPCODE_REFRACT3: return "refract3";
- case OPCODE_REFRACT4: return "refract4";
- case OPCODE_LEAVE: return "leave";
- case OPCODE_CONTINUE: return "continue";
- case OPCODE_TEST: return "test";
- case OPCODE_SWITCH: return "switch";
- case OPCODE_ENDSWITCH: return "endswitch";
+ case OPCODE_TEXGRAD: return "texgrad";
+ case OPCODE_TEXGRADOFFSET: return "texgradoffset";
+ case OPCODE_BREAKP: return "breakp";
+ case OPCODE_TEXSIZE: return "texsize";
+ case OPCODE_PHASE: return "phase";
+ case OPCODE_COMMENT: return "comment";
+ case OPCODE_END: return "end";
+ case OPCODE_PS_1_0: return "ps_1_0";
+ case OPCODE_PS_1_1: return "ps_1_1";
+ case OPCODE_PS_1_2: return "ps_1_2";
+ case OPCODE_PS_1_3: return "ps_1_3";
+ case OPCODE_PS_1_4: return "ps_1_4";
+ case OPCODE_PS_2_0: return "ps_2_0";
+ case OPCODE_PS_2_x: return "ps_2_x";
+ case OPCODE_PS_3_0: return "ps_3_0";
+ case OPCODE_VS_1_0: return "vs_1_0";
+ case OPCODE_VS_1_1: return "vs_1_1";
+ case OPCODE_VS_2_0: return "vs_2_0";
+ case OPCODE_VS_2_x: return "vs_2_x";
+ case OPCODE_VS_2_sw: return "vs_2_sw";
+ case OPCODE_VS_3_0: return "vs_3_0";
+ case OPCODE_VS_3_sw: return "vs_3_sw";
+ case OPCODE_WHILE: return "while";
+ case OPCODE_ENDWHILE: return "endwhile";
+ case OPCODE_COS: return "cos";
+ case OPCODE_SIN: return "sin";
+ case OPCODE_TAN: return "tan";
+ case OPCODE_ACOS: return "acos";
+ case OPCODE_ASIN: return "asin";
+ case OPCODE_ATAN: return "atan";
+ case OPCODE_ATAN2: return "atan2";
+ case OPCODE_COSH: return "cosh";
+ case OPCODE_SINH: return "sinh";
+ case OPCODE_TANH: return "tanh";
+ case OPCODE_ACOSH: return "acosh";
+ case OPCODE_ASINH: return "asinh";
+ case OPCODE_ATANH: return "atanh";
+ case OPCODE_DP1: return "dp1";
+ case OPCODE_DP2: return "dp2";
+ case OPCODE_TRUNC: return "trunc";
+ case OPCODE_FLOOR: return "floor";
+ case OPCODE_ROUND: return "round";
+ case OPCODE_ROUNDEVEN: return "roundEven";
+ case OPCODE_CEIL: return "ceil";
+ case OPCODE_EXP2: return "exp2";
+ case OPCODE_LOG2: return "log2";
+ case OPCODE_EXP: return "exp";
+ case OPCODE_LOG: return "log";
+ case OPCODE_POW: return "pow";
+ case OPCODE_F2B: return "f2b";
+ case OPCODE_B2F: return "b2f";
+ case OPCODE_F2I: return "f2i";
+ case OPCODE_I2F: return "i2f";
+ case OPCODE_F2U: return "f2u";
+ case OPCODE_U2F: return "u2f";
+ case OPCODE_B2I: return "b2i";
+ case OPCODE_I2B: return "i2b";
+ case OPCODE_ALL: return "all";
+ case OPCODE_ANY: return "any";
+ case OPCODE_NEG: return "neg";
+ case OPCODE_INEG: return "ineg";
+ case OPCODE_ISNAN: return "isnan";
+ case OPCODE_ISINF: return "isinf";
+ case OPCODE_NOT: return "not";
+ case OPCODE_OR: return "or";
+ case OPCODE_XOR: return "xor";
+ case OPCODE_AND: return "and";
+ case OPCODE_EQ: return "eq";
+ case OPCODE_NE: return "neq";
+ case OPCODE_FORWARD1: return "forward1";
+ case OPCODE_FORWARD2: return "forward2";
+ case OPCODE_FORWARD3: return "forward3";
+ case OPCODE_FORWARD4: return "forward4";
+ case OPCODE_REFLECT1: return "reflect1";
+ case OPCODE_REFLECT2: return "reflect2";
+ case OPCODE_REFLECT3: return "reflect3";
+ case OPCODE_REFLECT4: return "reflect4";
+ case OPCODE_REFRACT1: return "refract1";
+ case OPCODE_REFRACT2: return "refract2";
+ case OPCODE_REFRACT3: return "refract3";
+ case OPCODE_REFRACT4: return "refract4";
+ case OPCODE_LEAVE: return "leave";
+ case OPCODE_CONTINUE: return "continue";
+ case OPCODE_TEST: return "test";
+ case OPCODE_SWITCH: return "switch";
+ case OPCODE_ENDSWITCH: return "endswitch";
default:
ASSERT(false);
}
@@ -1121,10 +1136,10 @@
Shader::~Shader()
{
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(auto &inst : instruction)
{
- delete instruction[i];
- instruction[i] = 0;
+ delete inst;
+ inst = 0;
}
}
@@ -1168,12 +1183,12 @@
int Shader::size(unsigned long opcode) const
{
- return size(opcode, version);
+ return size(opcode, shaderModel);
}
- int Shader::size(unsigned long opcode, unsigned short version)
+ int Shader::size(unsigned long opcode, unsigned short shaderModel)
{
- if(version > 0x0300)
+ if(shaderModel > 0x0300)
{
ASSERT(false);
}
@@ -1320,7 +1335,7 @@
opcode != OPCODE_PHASE &&
opcode != OPCODE_END)
{
- if(version >= 0x0200)
+ if(shaderModel >= 0x0200)
{
length = (opcode & 0x0F000000) >> 24;
}
@@ -1335,7 +1350,7 @@
ASSERT(false);
}
- if(version == 0x0104)
+ if(shaderModel == 0x0104)
{
switch(opcode & 0x0000FFFF)
{
@@ -1423,9 +1438,9 @@
return shaderType;
}
- unsigned short Shader::getVersion() const
+ unsigned short Shader::getShaderModel() const
{
- return version;
+ return shaderModel;
}
void Shader::print(const char *fileName, ...) const
@@ -1439,9 +1454,9 @@
std::ofstream file(fullName, std::ofstream::out);
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- file << instruction[i]->string(shaderType, version) << std::endl;
+ file << inst->string(shaderType, shaderModel) << std::endl;
}
}
@@ -1449,7 +1464,7 @@
{
std::ofstream file(fileName, std::ofstream::out | std::ofstream::app);
- file << instruction[index]->string(shaderType, version) << std::endl;
+ file << instruction[index]->string(shaderType, shaderModel) << std::endl;
}
void Shader::append(Instruction *instruction)
@@ -1459,7 +1474,10 @@
void Shader::declareSampler(int i)
{
- usedSamplers |= 1 << i;
+ if(i >= 0 && i < 16)
+ {
+ usedSamplers |= 1 << i;
+ }
}
const Shader::Instruction *Shader::getInstruction(size_t i) const
@@ -1502,11 +1520,11 @@
calledFunctions.clear();
rescan = false;
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->isCall())
+ if(inst->isCall())
{
- calledFunctions.insert(instruction[i]->dst.label);
+ calledFunctions.insert(inst->dst.label);
}
}
@@ -1579,26 +1597,26 @@
dirtyConstantsI = 0;
dirtyConstantsB = 0;
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- switch(instruction[i]->opcode)
+ switch(inst->opcode)
{
case OPCODE_DEF:
- if(instruction[i]->dst.index + 1 > dirtyConstantsF)
+ if(inst->dst.index + 1 > dirtyConstantsF)
{
- dirtyConstantsF = instruction[i]->dst.index + 1;
+ dirtyConstantsF = inst->dst.index + 1;
}
break;
case OPCODE_DEFI:
- if(instruction[i]->dst.index + 1 > dirtyConstantsI)
+ if(inst->dst.index + 1 > dirtyConstantsI)
{
- dirtyConstantsI = instruction[i]->dst.index + 1;
+ dirtyConstantsI = inst->dst.index + 1;
}
break;
case OPCODE_DEFB:
- if(instruction[i]->dst.index + 1 > dirtyConstantsB)
+ if(inst->dst.index + 1 > dirtyConstantsB)
{
- dirtyConstantsB = instruction[i]->dst.index + 1;
+ dirtyConstantsB = inst->dst.index + 1;
}
break;
default:
@@ -1616,9 +1634,9 @@
containsDefine = false;
// Determine global presence of branching instructions
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- switch(instruction[i]->opcode)
+ switch(inst->opcode)
{
case OPCODE_CALLNZ:
case OPCODE_IF:
@@ -1629,22 +1647,22 @@
case OPCODE_BREAKP:
case OPCODE_LEAVE:
case OPCODE_CONTINUE:
- if(instruction[i]->src[0].type != PARAMETER_CONSTBOOL)
+ if(inst->src[0].type != PARAMETER_CONSTBOOL)
{
dynamicBranching = true;
}
- if(instruction[i]->opcode == OPCODE_LEAVE)
+ if(inst->opcode == OPCODE_LEAVE)
{
containsLeave = true;
}
- if(instruction[i]->isBreak())
+ if(inst->isBreak())
{
containsBreak = true;
}
- if(instruction[i]->opcode == OPCODE_CONTINUE)
+ if(inst->opcode == OPCODE_CONTINUE)
{
containsContinue = true;
}
@@ -1666,12 +1684,12 @@
for(unsigned int i = 0; i < instruction.size(); i++)
{
- // If statements
- if(instruction[i]->isBranch())
+ // If statements and loops
+ if(instruction[i]->isBranch() || instruction[i]->isLoop())
{
branchDepth++;
}
- else if(instruction[i]->opcode == OPCODE_ENDIF)
+ else if(instruction[i]->opcode == OPCODE_ENDIF || instruction[i]->isEndLoop())
{
branchDepth--;
}
@@ -1779,36 +1797,36 @@
void Shader::markFunctionAnalysis(unsigned int functionLabel, Analysis flag)
{
bool marker = false;
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(auto &inst : instruction)
{
if(!marker)
{
- if(instruction[i]->opcode == OPCODE_LABEL && instruction[i]->dst.label == functionLabel)
+ if(inst->opcode == OPCODE_LABEL && inst->dst.label == functionLabel)
{
marker = true;
}
}
else
{
- if(instruction[i]->opcode == OPCODE_RET)
+ if(inst->opcode == OPCODE_RET)
{
break;
}
- else if(instruction[i]->isCall())
+ else if(inst->isCall())
{
- markFunctionAnalysis(instruction[i]->dst.label, flag);
+ markFunctionAnalysis(inst->dst.label, flag);
}
- instruction[i]->analysis |= flag;
+ inst->analysis |= flag;
}
}
}
void Shader::analyzeSamplers()
{
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- switch(instruction[i]->opcode)
+ switch(inst->opcode)
{
case OPCODE_TEX:
case OPCODE_TEXBEM:
@@ -1824,15 +1842,17 @@
case OPCODE_TEXM3X2DEPTH:
case OPCODE_TEXLDD:
case OPCODE_TEXLDL:
+ case OPCODE_TEXLOD:
case OPCODE_TEXOFFSET:
- case OPCODE_TEXLDLOFFSET:
+ case OPCODE_TEXOFFSETBIAS:
+ case OPCODE_TEXLODOFFSET:
case OPCODE_TEXELFETCH:
case OPCODE_TEXELFETCHOFFSET:
case OPCODE_TEXGRAD:
case OPCODE_TEXGRADOFFSET:
{
- Parameter &dst = instruction[i]->dst;
- Parameter &src1 = instruction[i]->src[1];
+ Parameter &dst = inst->dst;
+ Parameter &src1 = inst->src[1];
if(majorVersion >= 2)
{
@@ -1856,13 +1876,13 @@
{
int callSiteIndex[2048] = {0};
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(auto &inst : instruction)
{
- if(instruction[i]->opcode == OPCODE_CALL || instruction[i]->opcode == OPCODE_CALLNZ)
+ if(inst->opcode == OPCODE_CALL || inst->opcode == OPCODE_CALLNZ)
{
- int label = instruction[i]->dst.label;
+ int label = inst->dst.label;
- instruction[i]->dst.callSite = callSiteIndex[label]++;
+ inst->dst.callSite = callSiteIndex[label]++;
}
}
}
@@ -1873,14 +1893,14 @@
dynamicallyIndexedInput = false;
dynamicallyIndexedOutput = false;
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->dst.rel.type == PARAMETER_ADDR ||
- instruction[i]->dst.rel.type == PARAMETER_LOOP ||
- instruction[i]->dst.rel.type == PARAMETER_TEMP ||
- instruction[i]->dst.rel.type == PARAMETER_CONST)
+ if(inst->dst.rel.type == PARAMETER_ADDR ||
+ inst->dst.rel.type == PARAMETER_LOOP ||
+ inst->dst.rel.type == PARAMETER_TEMP ||
+ inst->dst.rel.type == PARAMETER_CONST)
{
- switch(instruction[i]->dst.type)
+ switch(inst->dst.type)
{
case PARAMETER_TEMP: dynamicallyIndexedTemporaries = true; break;
case PARAMETER_INPUT: dynamicallyIndexedInput = true; break;
@@ -1891,12 +1911,12 @@
for(int j = 0; j < 3; j++)
{
- if(instruction[i]->src[j].rel.type == PARAMETER_ADDR ||
- instruction[i]->src[j].rel.type == PARAMETER_LOOP ||
- instruction[i]->src[j].rel.type == PARAMETER_TEMP ||
- instruction[i]->src[j].rel.type == PARAMETER_CONST)
+ if(inst->src[j].rel.type == PARAMETER_ADDR ||
+ inst->src[j].rel.type == PARAMETER_LOOP ||
+ inst->src[j].rel.type == PARAMETER_TEMP ||
+ inst->src[j].rel.type == PARAMETER_CONST)
{
- switch(instruction[i]->src[j].type)
+ switch(inst->src[j].type)
{
case PARAMETER_TEMP: dynamicallyIndexedTemporaries = true; break;
case PARAMETER_INPUT: dynamicallyIndexedInput = true; break;
diff --git a/src/Shader/Shader.hpp b/src/Shader/Shader.hpp
index ee69e8b..6755cd4 100644
--- a/src/Shader/Shader.hpp
+++ b/src/Shader/Shader.hpp
@@ -118,7 +118,6 @@
OPCODE_CMP, // D3DSIO_SETP
OPCODE_TEXLDL,
OPCODE_BREAKP,
- OPCODE_TEXSIZE,
OPCODE_PHASE = 0xFFFD,
OPCODE_COMMENT = 0xFFFE,
@@ -207,11 +206,15 @@
OPCODE_ISNAN,
OPCODE_ISINF,
OPCODE_TEXOFFSET,
- OPCODE_TEXLDLOFFSET,
+ OPCODE_TEXLODOFFSET,
OPCODE_TEXELFETCH,
OPCODE_TEXELFETCHOFFSET,
OPCODE_TEXGRAD,
OPCODE_TEXGRADOFFSET,
+ OPCODE_TEXBIAS,
+ OPCODE_TEXLOD,
+ OPCODE_TEXOFFSETBIAS,
+ OPCODE_TEXSIZE,
OPCODE_FLOATBITSTOINT,
OPCODE_FLOATBITSTOUINT,
OPCODE_INTBITSTOFLOAT,
@@ -393,6 +396,15 @@
ANALYSIS_LEAVE = 0x00000008,
};
+ struct Relative
+ {
+ ParameterType type : 8;
+ unsigned int index;
+ unsigned int swizzle : 8;
+ unsigned int scale;
+ bool deterministic; // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)
+ };
+
struct Parameter
{
union
@@ -401,14 +413,7 @@
{
unsigned int index; // For registers types
- struct
- {
- ParameterType type : 8;
- unsigned int index;
- unsigned int swizzle : 8;
- unsigned int scale;
- bool deterministic; // Equal accross shader instances run in lockstep (e.g. unrollable loop couters)
- } rel;
+ Relative rel;
};
float value[4]; // For float constants
@@ -453,7 +458,7 @@
};
};
- DestinationParameter() : mask(0xF), integer(false), saturate(false), partialPrecision(false), centroid(false), shift(0)
+ DestinationParameter() : mask(0xF), saturate(false), partialPrecision(false), centroid(false), shift(0)
{
}
@@ -461,7 +466,6 @@
std::string shiftString() const;
std::string maskString() const;
- bool integer : 1;
bool saturate : 1;
bool partialPrecision : 1;
bool centroid : 1;
@@ -474,6 +478,7 @@
{
}
+ std::string string(ShaderType shaderType, unsigned short version) const;
std::string swizzleString() const;
std::string preModifierString() const;
std::string postModifierString() const;
@@ -555,14 +560,14 @@
int getSerialID() const;
size_t getLength() const;
ShaderType getShaderType() const;
- unsigned short getVersion() const;
+ unsigned short getShaderModel() const;
void append(Instruction *instruction);
void declareSampler(int i);
const Instruction *getInstruction(size_t i) const;
int size(unsigned long opcode) const;
- static int size(unsigned long opcode, unsigned short version);
+ static int size(unsigned long opcode, unsigned short shaderModel);
void print(const char *fileName, ...) const;
void printInstruction(int index, const char *fileName) const;
@@ -629,7 +634,7 @@
union
{
- unsigned short version;
+ unsigned short shaderModel;
struct
{
diff --git a/src/Shader/ShaderCore.cpp b/src/Shader/ShaderCore.cpp
index 5799d3f..883131c 100644
--- a/src/Shader/ShaderCore.cpp
+++ b/src/Shader/ShaderCore.cpp
@@ -114,35 +114,30 @@
Float4 exponential2(RValue<Float4> x, bool pp)
{
- Float4 x0;
- Float4 x1;
- Int4 x2;
+ // This implementation is based on 2^(i + f) = 2^i * 2^f,
+ // where i is the integer part of x and f is the fraction.
- x0 = x;
-
+ // For 2^i we can put the integer part directly in the exponent of
+ // the IEEE-754 floating-point number. Clamp to prevent overflow
+ // past the representation of infinity.
+ Float4 x0 = x;
x0 = Min(x0, As<Float4>(Int4(0x43010000))); // 129.00000e+0f
x0 = Max(x0, As<Float4>(Int4(0xC2FDFFFF))); // -126.99999e+0f
- x1 = x0;
- x1 -= Float4(0.5f);
- x2 = RoundInt(x1);
- x1 = Float4(x2);
- x2 += Int4(0x0000007F); // 127
- x2 = x2 << 23;
- x0 -= x1;
- x1 = As<Float4>(Int4(0x3AF61905)); // 1.8775767e-3f
- x1 *= x0;
- x1 += As<Float4>(Int4(0x3C134806)); // 8.9893397e-3f
- x1 *= x0;
- x1 += As<Float4>(Int4(0x3D64AA23)); // 5.5826318e-2f
- x1 *= x0;
- x1 += As<Float4>(Int4(0x3E75EAD4)); // 2.4015361e-1f
- x1 *= x0;
- x1 += As<Float4>(Int4(0x3F31727B)); // 6.9315308e-1f
- x1 *= x0;
- x1 += As<Float4>(Int4(0x3F7FFFFF)); // 9.9999994e-1f
- x1 *= As<Float4>(x2);
- return x1;
+ Int4 i = RoundInt(x0 - Float4(0.5f));
+ Float4 ii = As<Float4>((i + Int4(127)) << 23); // Add single-precision bias, and shift into exponent.
+
+ // For the fractional part use a polynomial
+ // which approximates 2^f in the 0 to 1 range.
+ Float4 f = x0 - Float4(i);
+ Float4 ff = As<Float4>(Int4(0x3AF61905)); // 1.8775767e-3f
+ ff = ff * f + As<Float4>(Int4(0x3C134806)); // 8.9893397e-3f
+ ff = ff * f + As<Float4>(Int4(0x3D64AA23)); // 5.5826318e-2f
+ ff = ff * f + As<Float4>(Int4(0x3E75EAD4)); // 2.4015361e-1f
+ ff = ff * f + As<Float4>(Int4(0x3F31727B)); // 6.9315308e-1f
+ ff = ff * f + Float4(1.0f);
+
+ return ii * ff;
}
Float4 logarithm2(RValue<Float4> x, bool absolute, bool pp)
@@ -166,13 +161,14 @@
x1 += (x0 - Float4(1.0f)) * x2;
- return x1;
+ Int4 pos_inf_x = CmpEQ(As<Int4>(x), Int4(0x7F800000));
+ return As<Float4>((pos_inf_x & As<Int4>(x)) | (~pos_inf_x & As<Int4>(x1)));
}
Float4 exponential(RValue<Float4> x, bool pp)
{
// FIXME: Propagate the constant
- return exponential2(Float4(1.44269541f) * x, pp); // 1/ln(2)
+ return exponential2(Float4(1.44269504f) * x, pp); // 1/ln(2)
}
Float4 logarithm(RValue<Float4> x, bool absolute, bool pp)
@@ -226,7 +222,7 @@
Float4 rsq;
- if(!pp && rsqPrecision >= IEEE)
+ if(!pp)
{
rsq = Float4(1.0f) / Sqrt(abs);
}
@@ -238,10 +234,9 @@
{
rsq = rsq * (Float4(3.0f) - rsq * rsq * abs) * Float4(0.5f);
}
- }
- int big = 0x7F7FFFFF;
- rsq = Min(rsq, Float4((float&)big));
+ rsq = As<Float4>(CmpNEQ(As<Int4>(abs), Int4(0x7F800000)) & As<Int4>(rsq));
+ }
return rsq;
}
@@ -287,6 +282,21 @@
Float4 y = x * Float4(1.59154943e-1f); // 1/2pi
y = y - Round(y);
+ if(!pp)
+ {
+ // From the paper: "A Fast, Vectorizable Algorithm for Producing Single-Precision Sine-Cosine Pairs"
+ // This implementation passes OpenGL ES 3.0 precision requirements, at the cost of more operations:
+ // !pp : 17 mul, 7 add, 1 sub, 1 reciprocal
+ // pp : 4 mul, 2 add, 2 abs
+
+ Float4 y2 = y * y;
+ Float4 c1 = y2 * (y2 * (y2 * Float4(-0.0204391631f) + Float4(0.2536086171f)) + Float4(-1.2336977925f)) + Float4(1.0f);
+ Float4 s1 = y * (y2 * (y2 * (y2 * Float4(-0.0046075748f) + Float4(0.0796819754f)) + Float4(-0.645963615f)) + Float4(1.5707963235f));
+ Float4 c2 = (c1 * c1) - (s1 * s1);
+ Float4 s2 = Float4(2.0f) * s1 * c1;
+ return Float4(2.0f) * s2 * c2 * reciprocal(s2 * s2 + c2 * c2, pp, true);
+ }
+
const Float4 A = Float4(-16.0f);
const Float4 B = Float4(8.0f);
const Float4 C = Float4(7.75160950e-1f);
@@ -324,51 +334,95 @@
Float4 arcsin(RValue<Float4> x, bool pp)
{
- // x*(pi/2-sqrt(1-x*x)*pi/5)
- return x * (Float4(1.57079632e+0f) - Sqrt(Float4(1.0f) - x*x) * Float4(6.28318531e-1f));
+ if(false) // Simpler implementation fails even lowp precision tests
+ {
+ // x*(pi/2-sqrt(1-x*x)*pi/5)
+ return x * (Float4(1.57079632e+0f) - Sqrt(Float4(1.0f) - x*x) * Float4(6.28318531e-1f));
+ }
+ else
+ {
+ // From 4.4.45, page 81 of the Handbook of Mathematical Functions, by Milton Abramowitz and Irene Stegun
+ const Float4 half_pi(1.57079632f);
+ const Float4 a0(1.5707288f);
+ const Float4 a1(-0.2121144f);
+ const Float4 a2(0.0742610f);
+ const Float4 a3(-0.0187293f);
+ Float4 absx = Abs(x);
+ return As<Float4>(As<Int4>(half_pi - Sqrt(Float4(1.0f) - absx) * (a0 + absx * (a1 + absx * (a2 + absx * a3)))) ^
+ (As<Int4>(x) & Int4(0x80000000)));
+ }
+ }
+
+ // Approximation of atan in [0..1]
+ Float4 arctan_01(Float4 x, bool pp)
+ {
+ if(pp)
+ {
+ return x * (Float4(-0.27f) * x + Float4(1.05539816f));
+ }
+ else
+ {
+ // From 4.4.49, page 81 of the Handbook of Mathematical Functions, by Milton Abramowitz and Irene Stegun
+ const Float4 a2(-0.3333314528f);
+ const Float4 a4(0.1999355085f);
+ const Float4 a6(-0.1420889944f);
+ const Float4 a8(0.1065626393f);
+ const Float4 a10(-0.0752896400f);
+ const Float4 a12(0.0429096138f);
+ const Float4 a14(-0.0161657367f);
+ const Float4 a16(0.0028662257f);
+ Float4 x2 = x * x;
+ return (x + x * (x2 * (a2 + x2 * (a4 + x2 * (a6 + x2 * (a8 + x2 * (a10 + x2 * (a12 + x2 * (a14 + x2 * a16)))))))));
+ }
}
Float4 arctan(RValue<Float4> x, bool pp)
{
- Int4 O = CmpNLT(Abs(x), Float4(1.0f));
- Float4 y = As<Float4>((O & As<Int4>(Float4(1.0f) / x)) | (~O & As<Int4>(x))); // FIXME: Vector select
+ Float4 absx = Abs(x);
+ Int4 O = CmpNLT(absx, Float4(1.0f));
+ Float4 y = As<Float4>((O & As<Int4>(Float4(1.0f) / absx)) | (~O & As<Int4>(absx))); // FIXME: Vector select
- // Approximation of atan in [-1..1]
- Float4 theta = y * (Float4(-0.27f) * Abs(y) + Float4(1.05539816f));
-
- // +/-pi/2 depending on sign of x
- Float4 sgnPi_2 = As<Float4>(As<Int4>(Float4(1.57079632e+0f)) ^ (As<Int4>(x) & Int4(0x80000000)));
-
- theta = As<Float4>((O & As<Int4>(sgnPi_2 - theta)) | (~O & As<Int4>(theta))); // FIXME: Vector select
-
- return theta;
+ const Float4 half_pi(1.57079632f);
+ Float4 theta = arctan_01(y, pp);
+ return As<Float4>(((O & As<Int4>(half_pi - theta)) | (~O & As<Int4>(theta))) ^ // FIXME: Vector select
+ (As<Int4>(x) & Int4(0x80000000)));
}
Float4 arctan(RValue<Float4> y, RValue<Float4> x, bool pp)
{
+ const Float4 pi(3.14159265f); // pi
+ const Float4 minus_pi(-3.14159265f); // -pi
+ const Float4 half_pi(1.57079632f); // pi/2
+ const Float4 quarter_pi(7.85398163e-1f); // pi/4
+
// Rotate to upper semicircle when in lower semicircle
Int4 S = CmpLT(y, Float4(0.0f));
- Float4 theta = As<Float4>(S & As<Int4>(Float4(-3.14159265e+0f))); // -pi
+ Float4 theta = As<Float4>(S & As<Int4>(minus_pi));
Float4 x0 = As<Float4>((As<Int4>(y) & Int4(0x80000000)) ^ As<Int4>(x));
Float4 y0 = Abs(y);
// Rotate to right quadrant when in left quadrant
- Int4 Q = CmpLT(x0, Float4(0.0f));
- theta += As<Float4>(Q & As<Int4>(Float4(1.57079632e+0f))); // pi/2
- Float4 x1 = As<Float4>((Q & As<Int4>(y0)) | (~Q & As<Int4>(x0))); // FIXME: Vector select
- Float4 y1 = As<Float4>((Q & As<Int4>(-x0)) | (~Q & As<Int4>(y0))); // FIXME: Vector select
+ Int4 non_zero_y = CmpNEQ(y0, Float4(0.0f));
+ Int4 Q = CmpLT(x0, Float4(0.0f)) & non_zero_y;
+ theta += As<Float4>(Q & As<Int4>(half_pi));
+ Float4 x1 = As<Float4>((Q & As<Int4>(y0)) | (~Q & As<Int4>(x0))); // FIXME: Vector select
+ Float4 y1 = As<Float4>((Q & As<Int4>(-x0)) | (~Q & As<Int4>(y0))); // FIXME: Vector select
- // Rotate to first octant when in second octant
- Int4 O = CmpNLT(y1, x1);
- theta += As<Float4>(O & As<Int4>(Float4(7.85398163e-1f))); // pi/4
- Float4 x2 = As<Float4>((O & As<Int4>(Float4(7.07106781e-1f) * x1 + Float4(7.07106781e-1f) * y1)) | (~O & As<Int4>(x1))); // sqrt(2)/2 // FIXME: Vector select
- Float4 y2 = As<Float4>((O & As<Int4>(Float4(7.07106781e-1f) * y1 - Float4(7.07106781e-1f) * x1)) | (~O & As<Int4>(y1))); // FIXME: Vector select
+ // Mirror to first octant when in second octant
+ Int4 O = CmpNLT(y1, x1) & non_zero_y;
+ Float4 x2 = As<Float4>((O & As<Int4>(y1)) | (~O & As<Int4>(x1))); // FIXME: Vector select
+ Float4 y2 = As<Float4>((O & As<Int4>(x1)) | (~O & As<Int4>(y1))); // FIXME: Vector select
// Approximation of atan in [0..1]
- Float4 y_x = y2 / x2;
- theta += y_x * (Float4(-0.27f) * y_x + Float4(1.05539816f));
+ Int4 zero_x = CmpEQ(x2, Float4(0.0f));
+ Int4 inf_y = IsInf(y2); // Since x2 >= y2, this means x2 == y2 == inf, so we use 45 degrees or pi/4
+ Float4 atan2_theta = arctan_01(y2 / x2, pp);
+ theta += As<Float4>((~zero_x & ~inf_y & non_zero_y & ((O & As<Int4>(half_pi - atan2_theta)) | (~O & (As<Int4>(atan2_theta))))) | // FIXME: Vector select
+ (inf_y & As<Int4>(quarter_pi)));
- return theta;
+ // Recover loss of precision for tiny theta angles
+ Int4 precision_loss = S & Q & O & ~inf_y; // This combination results in (-pi + half_pi + half_pi - atan2_theta) which is equivalent to -atan2_theta
+ return As<Float4>((precision_loss & As<Int4>(-atan2_theta)) | (~precision_loss & As<Int4>(theta))); // FIXME: Vector select
}
Float4 sineh(RValue<Float4> x, bool pp)
@@ -431,6 +485,18 @@
row3 = UnpackHigh(tmp0, tmp1);
}
+ void transpose4x3(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3)
+ {
+ Int2 tmp0 = UnpackHigh(row0, row1);
+ Int2 tmp1 = UnpackHigh(row2, row3);
+ Int2 tmp2 = UnpackLow(row0, row1);
+ Int2 tmp3 = UnpackLow(row2, row3);
+
+ row0 = UnpackLow(tmp2, tmp3);
+ row1 = UnpackHigh(tmp2, tmp3);
+ row2 = UnpackLow(tmp0, tmp1);
+ }
+
void transpose4x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3)
{
Float4 tmp0 = UnpackLow(row0, row1);
@@ -656,7 +722,7 @@
void ShaderCore::rcpx(Vector4f &dst, const Vector4f &src, bool pp)
{
- Float4 rcp = reciprocal(src.x, pp, true);
+ Float4 rcp = reciprocal(src.x, pp, true, true);
dst.x = rcp;
dst.y = rcp;
@@ -708,24 +774,27 @@
void ShaderCore::imod(Vector4f &dst, const Vector4f &src0, const Vector4f &src1)
{
- cmp0i(dst.x, src1.x, src0.x, src1.x);
+ Float4 intMax(As<Float4>(Int4(INT_MAX)));
+ cmp0i(dst.x, src1.x, intMax, src1.x);
dst.x = As<Float4>(As<Int4>(src0.x) % As<Int4>(dst.x));
- cmp0i(dst.y, src1.y, src0.y, src1.y);
+ cmp0i(dst.y, src1.y, intMax, src1.y);
dst.y = As<Float4>(As<Int4>(src0.y) % As<Int4>(dst.y));
- cmp0i(dst.z, src1.z, src0.z, src1.z);
+ cmp0i(dst.z, src1.z, intMax, src1.z);
dst.z = As<Float4>(As<Int4>(src0.z) % As<Int4>(dst.z));
- cmp0i(dst.w, src1.w, src0.w, src1.w);
+ cmp0i(dst.w, src1.w, intMax, src1.w);
dst.w = As<Float4>(As<Int4>(src0.w) % As<Int4>(dst.w));
}
+
void ShaderCore::umod(Vector4f &dst, const Vector4f &src0, const Vector4f &src1)
{
- cmp0i(dst.x, src1.x, src0.x, src1.x);
+ Float4 uintMax(As<Float4>(UInt4(UINT_MAX)));
+ cmp0i(dst.x, src1.x, uintMax, src1.x);
dst.x = As<Float4>(As<UInt4>(src0.x) % As<UInt4>(dst.x));
- cmp0i(dst.y, src1.y, src0.y, src1.y);
+ cmp0i(dst.y, src1.y, uintMax, src1.y);
dst.y = As<Float4>(As<UInt4>(src0.y) % As<UInt4>(dst.y));
- cmp0i(dst.z, src1.z, src0.z, src1.z);
+ cmp0i(dst.z, src1.z, uintMax, src1.z);
dst.z = As<Float4>(As<UInt4>(src0.z) % As<UInt4>(dst.z));
- cmp0i(dst.w, src1.w, src0.w, src1.w);
+ cmp0i(dst.w, src1.w, uintMax, src1.w);
dst.w = As<Float4>(As<UInt4>(src0.w) % As<UInt4>(dst.w));
}
@@ -1027,6 +1096,22 @@
dst.w = src0.w * (src1.w - src2.w) + src2.w;
}
+ void ShaderCore::isinf(Vector4f &dst, const Vector4f &src)
+ {
+ dst.x = As<Float4>(IsInf(src.x));
+ dst.y = As<Float4>(IsInf(src.y));
+ dst.z = As<Float4>(IsInf(src.z));
+ dst.w = As<Float4>(IsInf(src.w));
+ }
+
+ void ShaderCore::isnan(Vector4f &dst, const Vector4f &src)
+ {
+ dst.x = As<Float4>(IsNan(src.x));
+ dst.y = As<Float4>(IsNan(src.y));
+ dst.z = As<Float4>(IsNan(src.z));
+ dst.w = As<Float4>(IsNan(src.w));
+ }
+
void ShaderCore::smooth(Vector4f &dst, const Vector4f &edge0, const Vector4f &edge1, const Vector4f &x)
{
Float4 tx = Min(Max((x.x - edge0.x) / (edge1.x - edge0.x), Float4(0.0f)), Float4(1.0f)); dst.x = tx * tx * (Float4(3.0f) - Float4(2.0f) * tx);
@@ -1515,9 +1600,9 @@
dst.w = arctanh(src.w, pp);
}
- void ShaderCore::expp(Vector4f &dst, const Vector4f &src, unsigned short version)
+ void ShaderCore::expp(Vector4f &dst, const Vector4f &src, unsigned short shaderModel)
{
- if(version < 0x0200)
+ if(shaderModel < 0x0200)
{
Float4 frc = Frac(src.x);
Float4 floor = src.x - frc;
@@ -1533,9 +1618,9 @@
}
}
- void ShaderCore::logp(Vector4f &dst, const Vector4f &src, unsigned short version)
+ void ShaderCore::logp(Vector4f &dst, const Vector4f &src, unsigned short shaderModel)
{
- if(version < 0x0200)
+ if(shaderModel < 0x0200)
{
Float4 tmp0;
Float4 tmp1;
diff --git a/src/Shader/ShaderCore.hpp b/src/Shader/ShaderCore.hpp
index c7b8be4..249e058 100644
--- a/src/Shader/ShaderCore.hpp
+++ b/src/Shader/ShaderCore.hpp
@@ -15,9 +15,9 @@
#ifndef sw_ShaderCore_hpp
#define sw_ShaderCore_hpp
-#include "Debug.hpp"
#include "Shader.hpp"
#include "Reactor/Reactor.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
@@ -82,6 +82,7 @@
Float4 dot4(const Vector4f &v0, const Vector4f &v1);
void transpose4x4(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3);
+ void transpose4x3(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3);
void transpose4x4(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
void transpose4x3(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
void transpose4x2(Float4 &row0, Float4 &row1, Float4 &row2, Float4 &row3);
@@ -282,6 +283,8 @@
void lit(Vector4f &dst, const Vector4f &src);
void att(Vector4f &dst, const Vector4f &src0, const Vector4f &src1);
void lrp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
+ void isinf(Vector4f &dst, const Vector4f &src);
+ void isnan(Vector4f &dst, const Vector4f &src);
void smooth(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
void packHalf2x16(Vector4f &dst, const Vector4f &src);
void unpackHalf2x16(Vector4f &dst, const Vector4f &src);
@@ -331,8 +334,8 @@
void acosh(Vector4f &dst, const Vector4f &src, bool pp = false);
void asinh(Vector4f &dst, const Vector4f &src, bool pp = false);
void atanh(Vector4f &dst, const Vector4f &src, bool pp = false);
- void expp(Vector4f &dst, const Vector4f &src, unsigned short version);
- void logp(Vector4f &dst, const Vector4f &src, unsigned short version);
+ void expp(Vector4f &dst, const Vector4f &src, unsigned short shaderModel);
+ void logp(Vector4f &dst, const Vector4f &src, unsigned short shaderModel);
void cmp0(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, const Vector4f &src2);
void cmp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, Control control);
void icmp(Vector4f &dst, const Vector4f &src0, const Vector4f &src1, Control control);
diff --git a/src/Shader/VertexPipeline.cpp b/src/Shader/VertexPipeline.cpp
index 8792884..129d8a8 100644
--- a/src/Shader/VertexPipeline.cpp
+++ b/src/Shader/VertexPipeline.cpp
@@ -14,9 +14,9 @@
#include "VertexPipeline.hpp"
-#include "Vertex.hpp"
-#include "Renderer.hpp"
-#include "Debug.hpp"
+#include "Renderer/Vertex.hpp"
+#include "Renderer/Renderer.hpp"
+#include "Common/Debug.hpp"
#include <string.h>
#include <stdlib.h>
diff --git a/src/Shader/VertexPipeline.hpp b/src/Shader/VertexPipeline.hpp
index e3c0cbe..0736afb 100644
--- a/src/Shader/VertexPipeline.hpp
+++ b/src/Shader/VertexPipeline.hpp
@@ -17,8 +17,8 @@
#include "VertexRoutine.hpp"
-#include "Context.hpp"
-#include "VertexProcessor.hpp"
+#include "Renderer/Context.hpp"
+#include "Renderer/VertexProcessor.hpp"
namespace sw
{
diff --git a/src/Shader/VertexProgram.cpp b/src/Shader/VertexProgram.cpp
index c9ed8aa..4f8ba1a 100644
--- a/src/Shader/VertexProgram.cpp
+++ b/src/Shader/VertexProgram.cpp
@@ -14,12 +14,12 @@
#include "VertexProgram.hpp"
-#include "Renderer.hpp"
#include "VertexShader.hpp"
-#include "Vertex.hpp"
-#include "Half.hpp"
#include "SamplerCore.hpp"
-#include "Debug.hpp"
+#include "Renderer/Renderer.hpp"
+#include "Renderer/Vertex.hpp"
+#include "Common/Half.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
@@ -28,7 +28,6 @@
{
ifDepth = 0;
loopRepDepth = 0;
- breakDepth = 0;
currentLabel = -1;
whileTest = false;
@@ -40,12 +39,12 @@
loopDepth = -1;
enableStack[0] = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
- if(shader && shader->containsBreakInstruction())
+ if(shader->containsBreakInstruction())
{
enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
- if(shader && shader->containsContinueInstruction())
+ if(shader->containsContinueInstruction())
{
enableContinue = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
@@ -58,19 +57,10 @@
VertexProgram::~VertexProgram()
{
- for(int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
- {
- delete sampler[i];
- }
}
void VertexProgram::pipeline(UInt& index)
{
- for(int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
- {
- sampler[i] = new SamplerCore(constants, state.samplerState[i]);
- }
-
if(!state.preTransformed)
{
program(index);
@@ -85,7 +75,7 @@
{
// shader->print("VertexShader-%0.8X.txt", state.shaderID);
- unsigned short version = shader->getVersion();
+ unsigned short shaderModel = shader->getShaderModel();
enableIndex = 0;
stackIndex = 0;
@@ -201,7 +191,7 @@
case Shader::OPCODE_ATT: att(d, s0, s1); break;
case Shader::OPCODE_EXP2X: exp2x(d, s0, pp); break;
case Shader::OPCODE_EXP2: exp2(d, s0, pp); break;
- case Shader::OPCODE_EXPP: expp(d, s0, version); break;
+ case Shader::OPCODE_EXPP: expp(d, s0, shaderModel); break;
case Shader::OPCODE_EXP: exp(d, s0, pp); break;
case Shader::OPCODE_FRC: frc(d, s0); break;
case Shader::OPCODE_TRUNC: trunc(d, s0); break;
@@ -212,11 +202,13 @@
case Shader::OPCODE_LIT: lit(d, s0); break;
case Shader::OPCODE_LOG2X: log2x(d, s0, pp); break;
case Shader::OPCODE_LOG2: log2(d, s0, pp); break;
- case Shader::OPCODE_LOGP: logp(d, s0, version); break;
+ case Shader::OPCODE_LOGP: logp(d, s0, shaderModel); break;
case Shader::OPCODE_LOG: log(d, s0, pp); break;
case Shader::OPCODE_LRP: lrp(d, s0, s1, s2); break;
case Shader::OPCODE_STEP: step(d, s0, s1); break;
case Shader::OPCODE_SMOOTH: smooth(d, s0, s1, s2); break;
+ case Shader::OPCODE_ISINF: isinf(d, s0); break;
+ case Shader::OPCODE_ISNAN: isnan(d, s0); break;
case Shader::OPCODE_FLOATBITSTOINT:
case Shader::OPCODE_FLOATBITSTOUINT:
case Shader::OPCODE_INTBITSTOFLOAT:
@@ -335,14 +327,15 @@
case Shader::OPCODE_AND: bitwise_and(d, s0, s1); break;
case Shader::OPCODE_EQ: equal(d, s0, s1); break;
case Shader::OPCODE_NE: notEqual(d, s0, s1); break;
- case Shader::OPCODE_TEXLDL: TEXLDL(d, s0, src1); break;
+ case Shader::OPCODE_TEXLDL: TEXLOD(d, s0, src1, s0.w); break;
+ case Shader::OPCODE_TEXLOD: TEXLOD(d, s0, src1, s2.x); break;
case Shader::OPCODE_TEX: TEX(d, s0, src1); break;
case Shader::OPCODE_TEXOFFSET: TEXOFFSET(d, s0, src1, s2); break;
- case Shader::OPCODE_TEXLDLOFFSET: TEXLDL(d, s0, src1, s2); break;
- case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1); break;
- case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCH(d, s0, src1, s2); break;
+ case Shader::OPCODE_TEXLODOFFSET: TEXLODOFFSET(d, s0, src1, s2, s3.x); break;
+ case Shader::OPCODE_TEXELFETCH: TEXELFETCH(d, s0, src1, s2.x); break;
+ case Shader::OPCODE_TEXELFETCHOFFSET: TEXELFETCHOFFSET(d, s0, src1, s2, s3.x); break;
case Shader::OPCODE_TEXGRAD: TEXGRAD(d, s0, src1, s2, s3); break;
- case Shader::OPCODE_TEXGRADOFFSET: TEXGRAD(d, s0, src1, s2, s3, s4); break;
+ case Shader::OPCODE_TEXGRADOFFSET: TEXGRADOFFSET(d, s0, src1, s2, s3, s4); break;
case Shader::OPCODE_TEXSIZE: TEXSIZE(d, s0.x, src1); break;
case Shader::OPCODE_END: break;
default:
@@ -351,21 +344,6 @@
if(dst.type != Shader::PARAMETER_VOID && dst.type != Shader::PARAMETER_LABEL && opcode != Shader::OPCODE_NOP)
{
- if(dst.integer)
- {
- switch(opcode)
- {
- case Shader::OPCODE_DIV:
- if(dst.x) d.x = Trunc(d.x);
- if(dst.y) d.y = Trunc(d.y);
- if(dst.z) d.z = Trunc(d.z);
- if(dst.w) d.w = Trunc(d.w);
- break;
- default:
- break; // No truncation to integer required when arguments are integer
- }
- }
-
if(dst.saturate)
{
if(dst.x) d.x = Max(d.x, Float4(0.0f));
@@ -432,7 +410,7 @@
break;
case Shader::PARAMETER_TEXCRDOUT:
// case Shader::PARAMETER_OUTPUT:
- if(version < 0x0300)
+ if(shaderModel < 0x0300)
{
if(dst.x) pDst.x = o[T0 + dst.index].x;
if(dst.y) pDst.y = o[T0 + dst.index].y;
@@ -563,7 +541,7 @@
break;
case Shader::PARAMETER_TEXCRDOUT:
// case Shader::PARAMETER_OUTPUT:
- if(version < 0x0300)
+ if(shaderModel < 0x0300)
{
if(dst.x) o[T0 + dst.index].x = d.x;
if(dst.y) o[T0 + dst.index].y = d.y;
@@ -1032,25 +1010,7 @@
void VertexProgram::BREAK()
{
- BasicBlock *deadBlock = Nucleus::createBasicBlock();
- BasicBlock *endBlock = loopRepEndBlock[loopRepDepth - 1];
-
- if(breakDepth == 0)
- {
- enableIndex = enableIndex - breakDepth;
- Nucleus::createBr(endBlock);
- }
- else
- {
- enableBreak = enableBreak & ~enableStack[enableIndex];
- Bool allBreak = SignMask(enableBreak) == 0x0;
-
- enableIndex = enableIndex - breakDepth;
- branch(allBreak, endBlock, deadBlock);
- }
-
- Nucleus::setInsertBlock(deadBlock);
- enableIndex = enableIndex + breakDepth;
+ enableBreak = enableBreak & ~enableStack[enableIndex];
}
void VertexProgram::BREAKC(Vector4f &src0, Vector4f &src1, Control control)
@@ -1059,12 +1019,12 @@
switch(control)
{
- case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break;
- case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x); break;
- case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break;
- case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x); break;
- case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break;
- case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x); break;
+ case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break;
+ case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x); break;
+ case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break;
+ case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x); break;
+ case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break;
+ case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x); break;
default:
ASSERT(false);
}
@@ -1088,17 +1048,7 @@
{
condition &= enableStack[enableIndex];
- BasicBlock *continueBlock = Nucleus::createBasicBlock();
- BasicBlock *endBlock = loopRepEndBlock[loopRepDepth - 1];
-
enableBreak = enableBreak & ~condition;
- Bool allBreak = SignMask(enableBreak) == 0x0;
-
- enableIndex = enableIndex - breakDepth;
- branch(allBreak, endBlock, continueBlock);
-
- Nucleus::setInsertBlock(continueBlock);
- enableIndex = enableIndex + breakDepth;
}
void VertexProgram::CONTINUE()
@@ -1242,7 +1192,6 @@
if(isConditionalIf[ifDepth])
{
- breakDepth--;
enableIndex--;
}
}
@@ -1288,7 +1237,6 @@
Nucleus::setInsertBlock(endBlock);
enableIndex--;
- enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
whileTest = false;
}
@@ -1298,11 +1246,8 @@
BasicBlock *endBlock = loopRepEndBlock[loopRepDepth];
- Nucleus::createBr(loopRepEndBlock[loopRepDepth]);
+ Nucleus::createBr(endBlock);
Nucleus::setInsertBlock(endBlock);
-
- enableIndex--;
- enableBreak = Int4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
}
void VertexProgram::IF(const Src &src)
@@ -1362,12 +1307,12 @@
switch(control)
{
- case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break;
- case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x); break;
- case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break;
- case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x); break;
- case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break;
- case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x); break;
+ case Shader::CONTROL_GT: condition = CmpNLE(src0.x, src1.x); break;
+ case Shader::CONTROL_EQ: condition = CmpEQ(src0.x, src1.x); break;
+ case Shader::CONTROL_GE: condition = CmpNLT(src0.x, src1.x); break;
+ case Shader::CONTROL_LT: condition = CmpLT(src0.x, src1.x); break;
+ case Shader::CONTROL_NE: condition = CmpNEQ(src0.x, src1.x); break;
+ case Shader::CONTROL_LE: condition = CmpLE(src0.x, src1.x); break;
default:
ASSERT(false);
}
@@ -1393,7 +1338,6 @@
ifFalseBlock[ifDepth] = falseBlock;
ifDepth++;
- breakDepth++;
}
void VertexProgram::LABEL(int labelIndex)
@@ -1438,7 +1382,6 @@
iteration[loopDepth] = iteration[loopDepth] - 1; // FIXME: --
loopRepDepth++;
- breakDepth = 0;
}
void VertexProgram::REP(const Src &integerRegister)
@@ -1465,7 +1408,6 @@
iteration[loopDepth] = iteration[loopDepth] - 1; // FIXME: --
loopRepDepth++;
- breakDepth = 0;
}
void VertexProgram::WHILE(const Src &temporaryRegister)
@@ -1482,7 +1424,7 @@
Int4 restoreBreak = enableBreak;
Int4 restoreContinue = enableContinue;
- // FIXME: jump(testBlock)
+ // TODO: jump(testBlock)
Nucleus::createBr(testBlock);
Nucleus::setInsertBlock(testBlock);
enableContinue = restoreContinue;
@@ -1491,6 +1433,7 @@
Int4 condition = As<Int4>(src.x);
condition &= enableStack[enableIndex - 1];
if(shader->containsLeaveInstruction()) condition &= enableLeave;
+ if(shader->containsBreakInstruction()) condition &= enableBreak;
enableStack[enableIndex] = condition;
Bool notAllFalse = SignMask(condition) != 0;
@@ -1502,21 +1445,25 @@
Nucleus::setInsertBlock(loopBlock);
loopRepDepth++;
- breakDepth = 0;
}
void VertexProgram::SWITCH()
{
- enableIndex++;
- enableStack[enableIndex] = Int4(0xFFFFFFFF);
-
BasicBlock *endBlock = Nucleus::createBasicBlock();
loopRepTestBlock[loopRepDepth] = nullptr;
loopRepEndBlock[loopRepDepth] = endBlock;
+ Int4 restoreBreak = enableBreak;
+
+ BasicBlock *currentBlock = Nucleus::getInsertBlock();
+
+ Nucleus::setInsertBlock(endBlock);
+ enableBreak = restoreBreak;
+
+ Nucleus::setInsertBlock(currentBlock);
+
loopRepDepth++;
- breakDepth = 0;
}
void VertexProgram::RET()
@@ -1565,62 +1512,59 @@
// FIXME: Use enableLeave in other control-flow constructs
}
- void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src &src1)
- {
- sampleTexture(dst, src1, src0, a0, a0, src0, Lod);
- }
-
void VertexProgram::TEX(Vector4f &dst, Vector4f &src0, const Src &src1)
{
- src0.w = Float(0.0f);
- sampleTexture(dst, src1, src0, a0, a0, src0, Lod);
+ dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), (src0), Base);
}
- void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2)
+ void VertexProgram::TEXOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset)
{
- src0.w = Float(0.0f);
- sampleTexture(dst, src1, src0, a0, a0, src2, {Lod, Offset});
+ dst = sampleTexture(src1, src0, (src0.x), (src0), (src0), offset, {Base, Offset});
}
- void VertexProgram::TEXLDL(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset)
+ void VertexProgram::TEXLOD(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
{
- sampleTexture(dst, src1, src0, a0, a0, offset, {Lod, Offset});
+ dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Lod);
}
- void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1)
+ void VertexProgram::TEXLODOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
{
- sampleTexture(dst, src1, src0, src0, src0, src0, Fetch);
+ dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Lod, Offset});
}
- void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset)
+ void VertexProgram::TEXELFETCH(Vector4f &dst, Vector4f &src0, const Src& src1, Float4 &lod)
{
- sampleTexture(dst, src1, src0, src0, src0, offset, {Fetch, Offset});
+ dst = sampleTexture(src1, src0, lod, (src0), (src0), (src0), Fetch);
}
- void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3)
+ void VertexProgram::TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &offset, Float4 &lod)
{
- sampleTexture(dst, src1, src0, src2, src3, src0, Grad);
+ dst = sampleTexture(src1, src0, lod, (src0), (src0), offset, {Fetch, Offset});
}
- void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &src2, Vector4f &src3, Vector4f &offset)
+ void VertexProgram::TEXGRAD(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy)
{
- sampleTexture(dst, src1, src0, src2, src3, offset, {Grad, Offset});
+ dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, src0, Grad);
+ }
+
+ void VertexProgram::TEXGRADOFFSET(Vector4f &dst, Vector4f &src0, const Src& src1, Vector4f &dsx, Vector4f &dsy, Vector4f &offset)
+ {
+ dst = sampleTexture(src1, src0, (src0.x), dsx, dsy, offset, {Grad, Offset});
}
void VertexProgram::TEXSIZE(Vector4f &dst, Float4 &lod, const Src &src1)
{
- Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[16]) + src1.index * sizeof(Texture);
- sampler[src1.index]->textureSize(texture, dst, lod);
+ Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + src1.index * sizeof(Texture);
+ dst = SamplerCore::textureSize(texture, lod);
}
- void VertexProgram::sampleTexture(Vector4f &c, const Src &s, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
+ Vector4f VertexProgram::sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{
Vector4f tmp;
if(s.type == Shader::PARAMETER_SAMPLER && s.rel.type == Shader::PARAMETER_VOID)
{
- Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + s.index * sizeof(Texture);
- sampler[s.index]->sampleTexture(texture, tmp, uvwq.x, uvwq.y, uvwq.z, uvwq.w, dsx, dsy, offset, function);
+ tmp = sampleTexture(s.index, uvwq, lod, dsx, dsy, offset, function);
}
else
{
@@ -1632,17 +1576,25 @@
{
If(index == i)
{
- Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + i * sizeof(Texture);
- sampler[i]->sampleTexture(texture, tmp, uvwq.x, uvwq.y, uvwq.z, uvwq.w, dsx, dsy, offset, function);
+ tmp = sampleTexture(i, uvwq, lod, dsx, dsy, offset, function);
// FIXME: When the sampler states are the same, we could use one sampler and just index the texture
}
}
}
}
+ Vector4f c;
c.x = tmp[(s.swizzle >> 0) & 0x3];
c.y = tmp[(s.swizzle >> 2) & 0x3];
c.z = tmp[(s.swizzle >> 4) & 0x3];
c.w = tmp[(s.swizzle >> 6) & 0x3];
+
+ return c;
+ }
+
+ Vector4f VertexProgram::sampleTexture(int sampler, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
+ {
+ Pointer<Byte> texture = data + OFFSET(DrawData, mipmap[TEXTURE_IMAGE_UNITS]) + sampler * sizeof(Texture);
+ return SamplerCore(constants, state.sampler[sampler]).sampleTexture(texture, uvwq.x, uvwq.y, uvwq.z, uvwq.w, lod, dsx, dsy, offset, function);
}
}
diff --git a/src/Shader/VertexProgram.hpp b/src/Shader/VertexProgram.hpp
index b537af3..c42ab71 100644
--- a/src/Shader/VertexProgram.hpp
+++ b/src/Shader/VertexProgram.hpp
@@ -17,10 +17,10 @@
#include "VertexRoutine.hpp"
#include "ShaderCore.hpp"
-#include "SamplerCore.hpp"
-#include "Stream.hpp"
-#include "Types.hpp"
+#include "SamplerCore.hpp"
+#include "Renderer/Stream.hpp"
+#include "Common/Types.hpp"
namespace sw
{
@@ -107,23 +107,21 @@
void SWITCH();
void RET();
void LEAVE();
- void TEXLDL(Vector4f &dst, Vector4f &src, const Src&);
void TEX(Vector4f &dst, Vector4f &src, const Src&);
- void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
- void TEXLDL(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
- void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&);
- void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2);
- void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3);
- void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &src2, Vector4f &src3, Vector4f &src4);
+ void TEXOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset);
+ void TEXLOD(Vector4f &dst, Vector4f &src, const Src&, Float4 &lod);
+ void TEXLODOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset, Float4 &lod);
+ void TEXELFETCH(Vector4f &dst, Vector4f &src, const Src&, Float4 &lod);
+ void TEXELFETCHOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &offset, Float4 &lod);
+ void TEXGRAD(Vector4f &dst, Vector4f &src, const Src&, Vector4f &dsx, Vector4f &dsy);
+ void TEXGRADOFFSET(Vector4f &dst, Vector4f &src, const Src&, Vector4f &dsx, Vector4f &dsy, Vector4f &offset);
void TEXSIZE(Vector4f &dst, Float4 &lod, const Src&);
- void sampleTexture(Vector4f &c, const Src &s, Vector4f &uvwq, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
-
- SamplerCore *sampler[VERTEX_TEXTURE_IMAGE_UNITS];
+ Vector4f sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
+ Vector4f sampleTexture(int sampler, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
int ifDepth;
int loopRepDepth;
- int breakDepth;
int currentLabel;
bool whileTest;
diff --git a/src/Shader/VertexRoutine.cpp b/src/Shader/VertexRoutine.cpp
index 0f1ccdf..2d7c2c6 100644
--- a/src/Shader/VertexRoutine.cpp
+++ b/src/Shader/VertexRoutine.cpp
@@ -15,11 +15,11 @@
#include "VertexRoutine.hpp"
#include "VertexShader.hpp"
-#include "Vertex.hpp"
-#include "Half.hpp"
-#include "Renderer.hpp"
#include "Constants.hpp"
-#include "Debug.hpp"
+#include "Renderer/Vertex.hpp"
+#include "Renderer/Renderer.hpp"
+#include "Common/Half.hpp"
+#include "Common/Debug.hpp"
namespace sw
{
diff --git a/src/Shader/VertexShader.cpp b/src/Shader/VertexShader.cpp
index 361c76f..33c2241 100644
--- a/src/Shader/VertexShader.cpp
+++ b/src/Shader/VertexShader.cpp
@@ -14,8 +14,8 @@
#include "VertexShader.hpp"
-#include "Vertex.hpp"
-#include "Debug.hpp"
+#include "Renderer/Vertex.hpp"
+#include "Common/Debug.hpp"
#include <string.h>
@@ -23,7 +23,7 @@
{
VertexShader::VertexShader(const VertexShader *vs) : Shader()
{
- version = 0x0300;
+ shaderModel = 0x0300;
positionRegister = Pos;
pointSizeRegister = Unused;
instanceIdDeclared = false;
@@ -226,16 +226,16 @@
void VertexShader::analyzeOutput()
{
- if(version < 0x0300)
+ if(shaderModel < 0x0300)
{
output[Pos][0] = Semantic(Shader::USAGE_POSITION, 0);
output[Pos][1] = Semantic(Shader::USAGE_POSITION, 0);
output[Pos][2] = Semantic(Shader::USAGE_POSITION, 0);
output[Pos][3] = Semantic(Shader::USAGE_POSITION, 0);
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- const DestinationParameter &dst = instruction[i]->dst;
+ const DestinationParameter &dst = inst->dst;
switch(dst.type)
{
@@ -285,15 +285,15 @@
}
else // Shader Model 3.0 input declaration
{
- for(unsigned int i = 0; i < instruction.size(); i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->opcode == Shader::OPCODE_DCL &&
- instruction[i]->dst.type == Shader::PARAMETER_OUTPUT)
+ if(inst->opcode == Shader::OPCODE_DCL &&
+ inst->dst.type == Shader::PARAMETER_OUTPUT)
{
- unsigned char usage = instruction[i]->usage;
- unsigned char usageIndex = instruction[i]->usageIndex;
+ unsigned char usage = inst->usage;
+ unsigned char usageIndex = inst->usageIndex;
- const DestinationParameter &dst = instruction[i]->dst;
+ const DestinationParameter &dst = inst->dst;
if(dst.x) output[dst.index][0] = Semantic(usage, usageIndex);
if(dst.y) output[dst.index][1] = Semantic(usage, usageIndex);
@@ -318,11 +318,12 @@
{
textureSampling = false;
- for(unsigned int i = 0; i < instruction.size() && !textureSampling; i++)
+ for(const auto &inst : instruction)
{
- if(instruction[i]->src[1].type == PARAMETER_SAMPLER)
+ if(inst->src[1].type == PARAMETER_SAMPLER)
{
textureSampling = true;
+ break;
}
}
}
diff --git a/src/SwiftShader/SwiftShader.vcxproj b/src/SwiftShader/SwiftShader.vcxproj
index 77ab670..ee9521e 100644
--- a/src/SwiftShader/SwiftShader.vcxproj
+++ b/src/SwiftShader/SwiftShader.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -29,43 +29,44 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{7B02CB19-4CDF-4F79-BC9B-7F3F6164A003}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -117,7 +118,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
- <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NO_SANITIZE_FUNCTION=;_DEBUG;_LIB;_HAS_EXCEPTIONS=0;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling>false</ExceptionHandling>
@@ -134,6 +135,7 @@
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -152,7 +154,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
- <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NO_SANITIZE_FUNCTION=;_DEBUG;_LIB;_HAS_EXCEPTIONS=0;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling>false</ExceptionHandling>
@@ -169,6 +171,7 @@
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -185,7 +188,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NO_SANITIZE_FUNCTION=;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -204,6 +207,7 @@
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -220,7 +224,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NO_SANITIZE_FUNCTION=;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -237,6 +241,7 @@
<FloatingPointExceptions>false</FloatingPointExceptions>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -256,7 +261,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NO_SANITIZE_FUNCTION=;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -275,6 +280,7 @@
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -294,7 +300,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<WholeProgramOptimization>false</WholeProgramOptimization>
- <AdditionalIncludeDirectories>..\;..\Main;..\Renderer;..\Shader;..\Common;..\SwiftAsm;..\libjpeg;..\SwiftShader;..\D3D9;..\Reactor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NO_SANITIZE_FUNCTION=;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -311,6 +317,7 @@
<FloatingPointExceptions>false</FloatingPointExceptions>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
@@ -323,6 +330,7 @@
<ClCompile Include="..\Common\Socket.cpp" />
<ClCompile Include="..\Common\Thread.cpp" />
<ClCompile Include="..\Main\Config.cpp" />
+ <ClCompile Include="..\Main\FrameBufferOzone.cpp" />
<ClCompile Include="..\Main\FrameBufferWin.cpp" />
<ClCompile Include="..\Renderer\ETC_Decoder.cpp" />
<ClCompile Include="..\Shader\Constants.cpp" />
diff --git a/src/SwiftShader/SwiftShader.vcxproj.filters b/src/SwiftShader/SwiftShader.vcxproj.filters
index b7618d0..64569cd 100644
--- a/src/SwiftShader/SwiftShader.vcxproj.filters
+++ b/src/SwiftShader/SwiftShader.vcxproj.filters
@@ -173,6 +173,9 @@
<ClCompile Include="..\Renderer\ETC_Decoder.cpp">
<Filter>Source Files\Renderer</Filter>
</ClCompile>
+ <ClCompile Include="..\Main\FrameBufferOzone.cpp">
+ <Filter>Source Files\Main</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Shader\Constants.hpp">
diff --git a/src/swiftshader.gni b/src/swiftshader.gni
index 9148762..01efa20 100644
--- a/src/swiftshader.gni
+++ b/src/swiftshader.gni
@@ -45,3 +45,14 @@
}
}
}
+
+template("swiftshader_static_library") {
+ static_library(target_name) {
+ configs -= configs_to_delete
+ configs += configs_to_add
+ forward_variables_from(invoker, "*", [ "configs" ])
+ if (defined(invoker.configs)) {
+ configs += invoker.configs
+ }
+ }
+}
diff --git a/tests/OGLSimpleCube/OGLSimpleCube.vcxproj b/tests/OGLSimpleCube/OGLSimpleCube.vcxproj
index 153d29e..2c56e57 100644
--- a/tests/OGLSimpleCube/OGLSimpleCube.vcxproj
+++ b/tests/OGLSimpleCube/OGLSimpleCube.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -22,31 +22,32 @@
<ProjectGuid>{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>OGLSimpleCube</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
diff --git a/tests/fuzzers/VertexRoutineFuzzer.cpp b/tests/fuzzers/VertexRoutineFuzzer.cpp
new file mode 100644
index 0000000..11ac1a4
--- /dev/null
+++ b/tests/fuzzers/VertexRoutineFuzzer.cpp
@@ -0,0 +1,213 @@
+// Copyright 2017 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "OpenGL/compiler/InitializeGlobals.h"
+#include "OpenGL/compiler/InitializeParseContext.h"
+#include "OpenGL/compiler/TranslatorASM.h"
+
+// TODO: Debug macros of the GLSL compiler clash with core SwiftShader's.
+// They should not be exposed through the interface headers above.
+#undef ASSERT
+#undef UNIMPLEMENTED
+
+#include "Renderer/VertexProcessor.hpp"
+#include "Shader/VertexProgram.hpp"
+
+#include <cstdint>
+#include <memory>
+#include <cassert>
+
+namespace {
+
+// TODO(cwallez@google.com): Like in ANGLE, disable most of the pool allocator for fuzzing
+// This is a helper class to make sure all the resources used by the compiler are initialized
+class ScopedPoolAllocatorAndTLS {
+ public:
+ ScopedPoolAllocatorAndTLS() {
+ InitializeParseContextIndex();
+ InitializePoolIndex();
+ SetGlobalPoolAllocator(&allocator);
+ }
+ ~ScopedPoolAllocatorAndTLS() {
+ SetGlobalPoolAllocator(nullptr);
+ FreePoolIndex();
+ FreeParseContextIndex();
+ }
+
+ private:
+ TPoolAllocator allocator;
+};
+
+// Trivial implementation of the glsl::Shader interface that fakes being an API-level
+// shader object.
+class FakeVS : public glsl::Shader {
+ public:
+ FakeVS(sw::VertexShader* bytecode) : bytecode(bytecode) {
+ }
+
+ sw::Shader *getShader() const override {
+ return bytecode;
+ }
+ sw::VertexShader *getVertexShader() const override {
+ return bytecode;
+ }
+
+ private:
+ sw::VertexShader* bytecode;
+};
+
+} // anonymous namespace
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+ // Data layout:
+ //
+ // byte: boolean states
+ // {
+ // byte: stream type
+ // byte: stream count and normalized
+ // } [MAX_VERTEX_INPUTS]
+ // {
+ // byte[32]: reserved sampler state
+ // } [VERTEX_TEXTURE_IMAGE_UNITS]
+ //
+ // char source[] // null terminated
+ const size_t kHeaderSize = 1 + 2 * sw::MAX_VERTEX_INPUTS + 32 * sw::VERTEX_TEXTURE_IMAGE_UNITS;
+
+ if(size <= kHeaderSize)
+ {
+ return 0;
+ }
+
+ if (data[size -1] != 0)
+ {
+ return 0;
+ }
+
+ std::unique_ptr<ScopedPoolAllocatorAndTLS> allocatorAndTLS(new ScopedPoolAllocatorAndTLS);
+ std::unique_ptr<sw::VertexShader> shader(new sw::VertexShader);
+ std::unique_ptr<FakeVS> fakeVS(new FakeVS(shader.get()));
+
+ std::unique_ptr<TranslatorASM> glslCompiler(new TranslatorASM(fakeVS.get(), GL_VERTEX_SHADER));
+
+ // TODO(cwallez@google.com): have a function to init to default values somewhere
+ ShBuiltInResources resources;
+ resources.MaxVertexAttribs = sw::MAX_VERTEX_INPUTS;
+ resources.MaxVertexUniformVectors = sw::VERTEX_UNIFORM_VECTORS - 3;
+ resources.MaxVaryingVectors = MIN(sw::MAX_VERTEX_OUTPUTS, sw::MAX_VERTEX_INPUTS);
+ resources.MaxVertexTextureImageUnits = sw::VERTEX_TEXTURE_IMAGE_UNITS;
+ resources.MaxCombinedTextureImageUnits = sw::TEXTURE_IMAGE_UNITS + sw::VERTEX_TEXTURE_IMAGE_UNITS;
+ resources.MaxTextureImageUnits = sw::TEXTURE_IMAGE_UNITS;
+ resources.MaxFragmentUniformVectors = sw::FRAGMENT_UNIFORM_VECTORS - 3;
+ resources.MaxDrawBuffers = sw::RENDERTARGETS;
+ resources.MaxVertexOutputVectors = 16; // ???
+ resources.MaxFragmentInputVectors = 15; // ???
+ resources.MinProgramTexelOffset = sw::MIN_PROGRAM_TEXEL_OFFSET;
+ resources.MaxProgramTexelOffset = sw::MAX_PROGRAM_TEXEL_OFFSET;
+ resources.OES_standard_derivatives = 1;
+ resources.OES_fragment_precision_high = 1;
+ resources.OES_EGL_image_external = 1;
+ resources.EXT_draw_buffers = 1;
+ resources.ARB_texture_rectangle = 1;
+ resources.MaxCallStackDepth = 16;
+
+ glslCompiler->Init(resources);
+
+ const char* glslSource = reinterpret_cast<const char*>(data + kHeaderSize);
+ if (!glslCompiler->compile(&glslSource, 1, SH_OBJECT_CODE))
+ {
+ return 0;
+ }
+
+ std::unique_ptr<sw::VertexShader> bytecodeShader(new sw::VertexShader(fakeVS->getVertexShader()));
+
+ sw::VertexProcessor::State state;
+
+ state.textureSampling = bytecodeShader->containsTextureSampling();
+ state.positionRegister = bytecodeShader->getPositionRegister();
+ state.pointSizeRegister = bytecodeShader->getPointSizeRegister();
+
+ state.preTransformed = (data[0] & 0x01) != 0;
+ state.superSampling = (data[0] & 0x02) != 0;
+ state.multiSampling = (data[0] & 0x04) != 0;
+
+ state.transformFeedbackQueryEnabled = (data[0] & 0x08) != 0;
+ state.transformFeedbackEnabled = (data[0] & 0x10) != 0;
+ state.verticesPerPrimitive = 1 + ((data[0] & 0x20) != 0) + ((data[0] & 0x40) != 0);
+
+ if((data[0] & 0x80) != 0) // Unused/reserved.
+ {
+ return 0;
+ }
+
+ constexpr int MAX_ATTRIBUTE_COMPONENTS = 4;
+
+ struct Stream
+ {
+ uint8_t count : BITS(MAX_ATTRIBUTE_COMPONENTS);
+ bool normalized : 1;
+ uint8_t reserved : 8 - BITS(MAX_ATTRIBUTE_COMPONENTS) - 1;
+ };
+
+ for(int i = 0; i < sw::MAX_VERTEX_INPUTS; i++)
+ {
+ sw::StreamType type = (sw::StreamType)data[1 + 2 * i + 0];
+ Stream stream = (Stream&)data[1 + 2 * i + 1];
+
+ if(type > sw::STREAMTYPE_LAST) return 0;
+ if(stream.count > MAX_ATTRIBUTE_COMPONENTS) return 0;
+ if(stream.reserved != 0) return 0;
+
+ state.input[i].type = type;
+ state.input[i].count = stream.count;
+ state.input[i].normalized = stream.normalized;
+ state.input[i].attribType = bytecodeShader->getAttribType(i);
+ }
+
+ for(unsigned int i = 0; i < sw::VERTEX_TEXTURE_IMAGE_UNITS; i++)
+ {
+ // TODO
+ // if(bytecodeShader->usesSampler(i))
+ // {
+ // state.samplerState[i] = context->sampler[sw::TEXTURE_IMAGE_UNITS + i].samplerState();
+ // }
+
+ for(int j = 0; j < 32; j++)
+ {
+ if(data[1 + 2 * sw::MAX_VERTEX_INPUTS + 32 * i + j] != 0)
+ {
+ return 0;
+ }
+ }
+ }
+
+ for(int i = 0; i < sw::MAX_VERTEX_OUTPUTS; i++)
+ {
+ state.output[i].xWrite = bytecodeShader->getOutput(i, 0).active();
+ state.output[i].yWrite = bytecodeShader->getOutput(i, 1).active();
+ state.output[i].zWrite = bytecodeShader->getOutput(i, 2).active();
+ state.output[i].wWrite = bytecodeShader->getOutput(i, 3).active();
+ }
+
+ sw::VertexProgram program(state, bytecodeShader.get());
+ program.generate();
+
+ sw::Routine *routine = program(L"VertexRoutine");
+ assert(routine);
+ const void *entry = routine->getEntry();
+ assert(entry); (void)entry;
+ delete routine;
+
+ return 0;
+}
diff --git a/tests/unittests/unittests.cpp b/tests/unittests/unittests.cpp
index 8861424..7ae84da 100644
--- a/tests/unittests/unittests.cpp
+++ b/tests/unittests/unittests.cpp
@@ -17,11 +17,15 @@
#include <EGL/egl.h>
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
#if defined(_WIN32)
#include <Windows.h>
#endif
+#define EXPECT_GLENUM_EQ(expected, actual) EXPECT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
+
class SwiftShaderTest : public testing::Test
{
protected:
@@ -37,151 +41,679 @@
EXPECT_NE((HMODULE)NULL, libGLESv2);
#endif
}
+
+ void compareColor(unsigned char referenceColor[4])
+ {
+ unsigned char color[4] = { 0 };
+ glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
+ EXPECT_EQ(color[0], referenceColor[0]);
+ EXPECT_EQ(color[1], referenceColor[1]);
+ EXPECT_EQ(color[2], referenceColor[2]);
+ EXPECT_EQ(color[3], referenceColor[3]);
+ }
+
+ void Initialize(int version, bool withChecks)
+ {
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+
+ display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ if(withChecks)
+ {
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_NE(EGL_NO_DISPLAY, display);
+
+ eglQueryString(display, EGL_VENDOR);
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
+ }
+
+ EGLint major;
+ EGLint minor;
+ EGLBoolean initialized = eglInitialize(display, &major, &minor);
+
+ if(withChecks)
+ {
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ((EGLBoolean)EGL_TRUE, initialized);
+ EXPECT_EQ(1, major);
+ EXPECT_EQ(4, minor);
+
+ const char *eglVendor = eglQueryString(display, EGL_VENDOR);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_STREQ("Google Inc.", eglVendor);
+
+ const char *eglVersion = eglQueryString(display, EGL_VERSION);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_THAT(eglVersion, testing::HasSubstr("1.4 SwiftShader "));
+ }
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+
+ const EGLint configAttributes[] =
+ {
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_ALPHA_SIZE, 8,
+ EGL_NONE
+ };
+ EGLint num_config = -1;
+ EGLBoolean success = eglChooseConfig(display, configAttributes, &config, 1, &num_config);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(num_config, 1);
+ EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+
+ if(withChecks)
+ {
+ EGLint conformant = 0;
+ eglGetConfigAttrib(display, config, EGL_CONFORMANT, &conformant);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_TRUE(conformant & EGL_OPENGL_ES2_BIT);
+
+ EGLint renderableType = 0;
+ eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_TRUE(renderableType & EGL_OPENGL_ES2_BIT);
+
+ EGLint surfaceType = 0;
+ eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &surfaceType);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_TRUE(surfaceType & EGL_WINDOW_BIT);
+ }
+
+ EGLint surfaceAttributes[] =
+ {
+ EGL_WIDTH, 1920,
+ EGL_HEIGHT, 1080,
+ EGL_NONE
+ };
+
+ surface = eglCreatePbufferSurface(display, config, surfaceAttributes);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_NE(EGL_NO_SURFACE, surface);
+
+ EGLint contextAttributes[] =
+ {
+ EGL_CONTEXT_CLIENT_VERSION, version,
+ EGL_NONE
+ };
+
+ context = eglCreateContext(display, config, NULL, contextAttributes);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_NE(EGL_NO_CONTEXT, context);
+
+ success = eglMakeCurrent(display, surface, surface, context);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+
+ if(withChecks)
+ {
+ EGLDisplay currentDisplay = eglGetCurrentDisplay();
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(display, currentDisplay);
+
+ EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(surface, currentDrawSurface);
+
+ EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(surface, currentReadSurface);
+
+ EGLContext currentContext = eglGetCurrentContext();
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(context, currentContext);
+ }
+
+ EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
+ }
+
+ void Uninitialize()
+ {
+ EGLBoolean success = eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+
+ EGLDisplay currentDisplay = eglGetCurrentDisplay();
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(EGL_NO_DISPLAY, currentDisplay);
+
+ EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(EGL_NO_SURFACE, currentDrawSurface);
+
+ EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(EGL_NO_SURFACE, currentReadSurface);
+
+ EGLContext currentContext = eglGetCurrentContext();
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ(EGL_NO_CONTEXT, currentContext);
+
+ success = eglDestroyContext(display, context);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+
+ success = eglDestroySurface(display, surface);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+
+ success = eglTerminate(display);
+ EXPECT_EQ(EGL_SUCCESS, eglGetError());
+ EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+ }
+
+ GLuint createProgram(const std::string& vs, const std::string& fs)
+ {
+ GLuint program = glCreateProgram();
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ GLuint vsShader = glCreateShader(GL_VERTEX_SHADER);
+ const char* vsSource[1] = { vs.c_str() };
+ glShaderSource(vsShader, 1, vsSource, nullptr);
+ glCompileShader(vsShader);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ GLuint fsShader = glCreateShader(GL_FRAGMENT_SHADER);
+ const char* fsSource[1] = { fs.c_str() };
+ glShaderSource(fsShader, 1, fsSource, nullptr);
+ glCompileShader(fsShader);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ glAttachShader(program, vsShader);
+ glAttachShader(program, fsShader);
+ glLinkProgram(program);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ return program;
+ }
+
+ void drawQuad(GLuint program)
+ {
+ GLint prevProgram = 0;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram);
+
+ glUseProgram(program);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ GLint posLoc = glGetAttribLocation(program, "position");
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ GLint location = glGetUniformLocation(program, "tex");
+ ASSERT_NE(-1, location);
+ glUniform1i(location, 0);
+
+ float vertices[18] = { -1.0f, 1.0f, 0.5f,
+ -1.0f, -1.0f, 0.5f,
+ 1.0f, -1.0f, 0.5f,
+ -1.0f, 1.0f, 0.5f,
+ 1.0f, -1.0f, 0.5f,
+ 1.0f, 1.0f, 0.5f };
+
+ glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, vertices);
+ glEnableVertexAttribArray(posLoc);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
+ glDisableVertexAttribArray(posLoc);
+ glUseProgram(prevProgram);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+ }
+
+ EGLDisplay getDisplay() const { return display; }
+ EGLDisplay getConfig() const { return config; }
+ EGLSurface getSurface() const { return surface; }
+ EGLContext getContext() const { return context; }
+private:
+ EGLDisplay display;
+ EGLConfig config;
+ EGLSurface surface;
+ EGLContext context;
};
TEST_F(SwiftShaderTest, Initalization)
{
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_NE(EGL_NO_DISPLAY, display);
-
- eglQueryString(display, EGL_VENDOR);
- EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-
- EGLint major;
- EGLint minor;
- EGLBoolean initialized = eglInitialize(display, &major, &minor);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ((EGLBoolean)EGL_TRUE, initialized);
- EXPECT_EQ(1, major);
- EXPECT_EQ(4, minor);
-
- const char *eglVendor = eglQueryString(display, EGL_VENDOR);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_STREQ("Google Inc.", eglVendor);
-
- const char *eglVersion = eglQueryString(display, EGL_VERSION);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_THAT(eglVersion, testing::HasSubstr("1.4 SwiftShader "));
-
- eglBindAPI(EGL_OPENGL_ES_API);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
- const EGLint configAttributes[] =
- {
- EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE
- };
-
- EGLConfig config;
- EGLint num_config = -1;
- EGLBoolean success = eglChooseConfig(display, configAttributes, &config, 1, &num_config);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(num_config, 1);
- EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
-
- EGLint conformant = 0;
- eglGetConfigAttrib(display, config, EGL_CONFORMANT, &conformant);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_TRUE(conformant & EGL_OPENGL_ES2_BIT);
-
- EGLint renderableType = 0;
- eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_TRUE(renderableType & EGL_OPENGL_ES2_BIT);
-
- EGLint surfaceType = 0;
- eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &surfaceType);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_TRUE(surfaceType & EGL_WINDOW_BIT);
-
- EGLint surfaceAttributes[] =
- {
- EGL_WIDTH, 1920,
- EGL_HEIGHT, 1080,
- EGL_NONE
- };
-
- EGLSurface surface = eglCreatePbufferSurface(display, config, surfaceAttributes);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_NE(EGL_NO_SURFACE, surface);
-
- EGLint contextAttributes[] =
- {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
- EGLContext context = eglCreateContext(display, config, NULL, contextAttributes);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_NE(EGL_NO_CONTEXT, context);
-
- success = eglMakeCurrent(display, surface, surface, context);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
-
- EGLDisplay currentDisplay = eglGetCurrentDisplay();
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(display, currentDisplay);
-
- EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(surface, currentDrawSurface);
-
- EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(surface, currentReadSurface);
-
- EGLContext currentContext = eglGetCurrentContext();
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(context, currentContext);
-
- EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
+ Initialize(2, true);
const GLubyte *glVendor = glGetString(GL_VENDOR);
- EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
+ EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
EXPECT_STREQ("Google Inc.", (const char*)glVendor);
const GLubyte *glRenderer = glGetString(GL_RENDERER);
- EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
+ EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
EXPECT_STREQ("Google SwiftShader", (const char*)glRenderer);
const GLubyte *glVersion = glGetString(GL_VERSION);
- EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
+ EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
EXPECT_THAT((const char*)glVersion, testing::HasSubstr("OpenGL ES 2.0 SwiftShader "));
- success = eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+ Uninitialize();
+}
- currentDisplay = eglGetCurrentDisplay();
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(EGL_NO_DISPLAY, currentDisplay);
+// Note: GL_ARB_texture_rectangle is part of gl2extchromium.h in the Chromium repo
+// GL_ARB_texture_rectangle
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
- currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(EGL_NO_SURFACE, currentDrawSurface);
+#ifndef GL_SAMPLER_2D_RECT_ARB
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#endif
- currentReadSurface = eglGetCurrentSurface(EGL_READ);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(EGL_NO_SURFACE, currentReadSurface);
+#ifndef GL_TEXTURE_BINDING_RECTANGLE_ARB
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#endif
- currentContext = eglGetCurrentContext();
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ(EGL_NO_CONTEXT, currentContext);
+#ifndef GL_TEXTURE_RECTANGLE_ARB
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#endif
- success = eglDestroyContext(display, context);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+#ifndef GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
- success = eglDestroySurface(display, surface);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+#endif // GL_ARB_texture_rectangle
- success = eglTerminate(display);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
- EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
+// Test using TexImage2D to define a rectangle texture
+
+TEST_F(SwiftShaderTest, TextureRectangle_TexImage2D)
+{
+ Initialize(2, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+
+ // Defining level 0 is allowed
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ // Defining level other than 0 is not allowed
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+
+ GLint maxSize = 0;
+ glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &maxSize);
+
+ // Defining a texture of the max size is allowed
+ {
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize, maxSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ GLenum error = glGetError();
+ ASSERT_TRUE(error == GL_NO_ERROR || error == GL_OUT_OF_MEMORY);
+ }
+
+ // Defining a texture larger than the max size is disallowed
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize + 1, maxSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, maxSize, maxSize + 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+
+ Uninitialize();
+}
+
+// Test using CompressedTexImage2D cannot be used on a retangle texture
+TEST_F(SwiftShaderTest, TextureRectangle_CompressedTexImage2DDisallowed)
+{
+ Initialize(2, false);
+
+ const char data[128] = { 0 };
+
+ // Control case: 2D texture
+ {
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16, 0, 128, data);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+ }
+
+ // Rectangle textures cannot be compressed
+ {
+ GLuint tex = 2;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ glCompressedTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16, 0, 128, data);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+ }
+
+ Uninitialize();
+}
+
+// Test using TexStorage2D to define a rectangle texture (ES3)
+TEST_F(SwiftShaderTest, TextureRectangle_TexStorage2D)
+{
+ Initialize(3, false);
+
+ // Defining one level is allowed
+ {
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, 16, 16);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+ }
+
+ // Having more than one level is not allowed
+ {
+ GLuint tex = 2;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ // Use 5 levels because the EXT_texture_storage extension requires a mip chain all the way
+ // to a 1x1 mip.
+ glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 5, GL_RGBA8UI, 16, 16);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+ }
+
+ GLint maxSize = 0;
+ glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &maxSize);
+
+ // Defining a texture of the max size is allowed but still allow for OOM
+ {
+ GLuint tex = 3;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize, maxSize);
+ GLenum error = glGetError();
+ ASSERT_TRUE(error == GL_NO_ERROR || error == GL_OUT_OF_MEMORY);
+ }
+
+ // Defining a texture larger than the max size is disallowed
+ {
+ GLuint tex = 4;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize + 1, maxSize);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+ glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8UI, maxSize, maxSize + 1);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+ }
+
+ // Compressed formats are disallowed
+ GLuint tex = 5;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ glTexStorage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+
+ Uninitialize();
+}
+
+// Test validation of disallowed texture parameters
+TEST_F(SwiftShaderTest, TextureRectangle_TexParameterRestriction)
+{
+ Initialize(3, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+
+ // Only wrap mode CLAMP_TO_EDGE is supported
+ // Wrap S
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+
+ // Wrap T
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+
+ // Min filter has to be nearest or linear
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ EXPECT_GLENUM_EQ(GL_INVALID_ENUM, glGetError());
+
+ // Base level has to be 0
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 0);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_BASE_LEVEL, 1);
+ EXPECT_GLENUM_EQ(GL_INVALID_OPERATION, glGetError());
+
+ Uninitialize();
+}
+
+// Test validation of "level" in FramebufferTexture2D
+TEST_F(SwiftShaderTest, TextureRectangle_FramebufferTexture2DLevel)
+{
+ Initialize(3, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ GLuint fbo = 1;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ // Using level 0 of a rectangle texture is valid.
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
+ EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ // Setting level != 0 is invalid
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 1);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+
+ Uninitialize();
+}
+
+// Test sampling from a rectangle texture
+TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangle)
+{
+ Initialize(3, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ unsigned char green[4] = { 0, 255, 0, 255 };
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, green);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ const std::string vs =
+ "attribute vec4 position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
+ "}\n";
+
+ const std::string fs =
+ "#extension GL_ARB_texture_rectangle : require\n"
+ "precision mediump float;\n"
+ "uniform sampler2DRect tex;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2DRect(tex, vec2(0, 0));\n"
+ "}\n";
+
+ GLuint program = createProgram(vs, fs);
+
+ glUseProgram(program);
+ GLint location = glGetUniformLocation(program, "tex");
+ ASSERT_NE(-1, location);
+ glUniform1i(location, 0);
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ drawQuad(program);
+
+ compareColor(green);
+
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ Uninitialize();
+}
+
+// Test sampling from a rectangle texture
+TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3)
+{
+ Initialize(3, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ unsigned char green[4] = { 0, 255, 0, 255 };
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, green);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ const std::string vs =
+ "#version 300 es\n"
+ "in vec4 position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(position.xy, 0.0, 1.0);\n"
+ "}\n";
+
+ const std::string fs =
+ "#version 300 es\n"
+ "#extension GL_ARB_texture_rectangle : require\n"
+ "precision mediump float;\n"
+ "uniform sampler2DRect tex;\n"
+ "out vec4 fragColor;\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = texture(tex, vec2(0, 0));\n"
+ "}\n";
+
+ GLuint program = createProgram(vs, fs);
+ glUseProgram(program);
+ GLint location = glGetUniformLocation(program, "tex");
+ ASSERT_NE(-1, location);
+ glUniform1i(location, 0);
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ drawQuad(program);
+
+ compareColor(green);
+
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ Uninitialize();
+}
+
+// Test attaching a rectangle texture and rendering to it.
+TEST_F(SwiftShaderTest, TextureRectangle_RenderToRectangle)
+{
+ Initialize(3, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ unsigned char black[4] = { 0, 0, 0, 255 };
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+
+ GLuint fbo = 1;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
+ EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ // Clearing a texture is just as good as checking we can render to it, right?
+ glClearColor(0.0, 1.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ unsigned char green[4] = { 0, 255, 0, 255 };
+ compareColor(green);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ Uninitialize();
+}
+
+TEST_F(SwiftShaderTest, TextureRectangle_DefaultSamplerParameters)
+{
+ Initialize(3, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+
+ GLint minFilter = 0;
+ glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, &minFilter);
+ EXPECT_GLENUM_EQ(GL_LINEAR, minFilter);
+
+ GLint wrapS = 0;
+ glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, &wrapS);
+ EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, wrapS);
+
+ GLint wrapT = 0;
+ glGetTexParameteriv(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, &wrapT);
+ EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, wrapT);
+
+ Uninitialize();
+}
+
+// Test glCopyTexImage with rectangle textures (ES3)
+TEST_F(SwiftShaderTest, TextureRectangle_CopyTexImage)
+{
+ Initialize(3, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glClearColor(0, 1, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ // Error case: level != 0
+ glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, GL_RGBA8, 0, 0, 1, 1, 0);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+
+ // level = 0 works and defines the texture.
+ glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 0, 0, 1, 1, 0);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ GLuint fbo = 1;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
+
+ unsigned char green[4] = { 0, 255, 0, 255 };
+ compareColor(green);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ Uninitialize();
+}
+
+// Test glCopyTexSubImage with rectangle textures (ES3)
+TEST_F(SwiftShaderTest, TextureRectangle_CopyTexSubImage)
+{
+ Initialize(3, false);
+
+ GLuint tex = 1;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
+ unsigned char black[4] = { 0, 0, 0, 255 };
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glClearColor(0, 1, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ // Error case: level != 0
+ glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 1, 0, 0, 0, 0, 1, 1);
+ EXPECT_GLENUM_EQ(GL_INVALID_VALUE, glGetError());
+
+ // level = 0 works and defines the texture.
+ glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, 0, 0, 1, 1);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ GLuint fbo = 1;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, tex, 0);
+
+ unsigned char green[4] = { 0, 255, 0, 255 };
+ compareColor(green);
+ EXPECT_GLENUM_EQ(GL_NONE, glGetError());
+
+ Uninitialize();
}
diff --git a/tests/unittests/unittests.vcxproj b/tests/unittests/unittests.vcxproj
index 537801f..b92398f 100644
--- a/tests/unittests/unittests.vcxproj
+++ b/tests/unittests/unittests.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -22,32 +22,32 @@
<ProjectGuid>{CF8EBC89-8762-49DC-9440-6C82B3499913}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>unittests</RootNamespace>
- <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@@ -96,6 +96,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)include\;$(SolutionDir)third_party\googletest\googletest\include\;$(SolutionDir)third_party\googletest\googletest\;$(SolutionDir)third_party\googletest\googlemock\include\;SubmoduleCheck;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>
</ForcedIncludeFiles>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -113,6 +114,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)include\;$(SolutionDir)third_party\googletest\googletest\include\;$(SolutionDir)third_party\googletest\googletest\;$(SolutionDir)third_party\googletest\googlemock\include\;SubmoduleCheck;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>
</ForcedIncludeFiles>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -132,6 +134,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)include\;$(SolutionDir)third_party\googletest\googletest\include\;$(SolutionDir)third_party\googletest\googletest\;$(SolutionDir)third_party\googletest\googlemock\include\;SubmoduleCheck;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>
</ForcedIncludeFiles>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -153,6 +156,7 @@
<AdditionalIncludeDirectories>$(SolutionDir)include\;$(SolutionDir)third_party\googletest\googletest\include\;$(SolutionDir)third_party\googletest\googletest\;$(SolutionDir)third_party\googletest\googlemock\include\;SubmoduleCheck;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ForcedIncludeFiles>
</ForcedIncludeFiles>
+ <TreatSpecificWarningsAsErrors>4018;5038</TreatSpecificWarningsAsErrors>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
diff --git a/tests/unittests/unittests.vcxproj.user b/tests/unittests/unittests.vcxproj.user
index 234e386..567b191 100644
--- a/tests/unittests/unittests.vcxproj.user
+++ b/tests/unittests/unittests.vcxproj.user
@@ -3,6 +3,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerEnvironment>PATH=$(SolutionDir)lib\$(Configuration)_$(Platform)</LocalDebuggerEnvironment>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments>--gtest_break_on_failure</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerEnvironment>PATH=$(SolutionDir)lib\$(Configuration)_$(Platform)</LocalDebuggerEnvironment>
@@ -11,6 +12,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerEnvironment>PATH=$(SolutionDir)lib\$(Configuration)_$(Platform)</LocalDebuggerEnvironment>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments>--gtest_break_on_failure</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerEnvironment>PATH=$(SolutionDir)lib\$(Configuration)_$(Platform)</LocalDebuggerEnvironment>
diff --git a/third_party/LLVM/Android.mk b/third_party/LLVM/Android.mk
index a3dcdae..069645d 100644
--- a/third_party/LLVM/Android.mk
+++ b/third_party/LLVM/Android.mk
@@ -396,8 +396,8 @@
lib/VMCore/ValueTypes.cpp \
lib/VMCore/Verifier.cpp \
-
-LOCAL_CFLAGS += -DLOG_TAG=\"libLLVM_swiftshader\" \
+LOCAL_CFLAGS += \
+ -DLOG_TAG=\"libLLVM_swiftshader\" \
-Wall \
-Werror \
-Wno-implicit-exception-spec-mismatch \
@@ -410,6 +410,7 @@
-Wno-unused-parameter \
-Wno-unused-private-field \
-Wno-unused-variable \
+ -Wno-unknown-warning-option
ifneq (16,${PLATFORM_SDK_VERSION})
LOCAL_CFLAGS += -Xclang -fuse-init-array
diff --git a/third_party/LLVM/BUILD.gn b/third_party/LLVM/BUILD.gn
index 3fc4d22..ad6b576 100644
--- a/third_party/LLVM/BUILD.gn
+++ b/third_party/LLVM/BUILD.gn
@@ -463,6 +463,8 @@
include_dirs += [ "include-linux" ]
} else if (is_mac) {
include_dirs += [ "include-osx" ]
+ } else if (is_fuchsia) {
+ include_dirs += [ "include-fuchsia" ]
}
include_dirs += [ "include" ]
diff --git a/third_party/LLVM/include-fuchsia/llvm/Config/config.h b/third_party/LLVM/include-fuchsia/llvm/Config/config.h
new file mode 100644
index 0000000..0e46979
--- /dev/null
+++ b/third_party/LLVM/include-fuchsia/llvm/Config/config.h
@@ -0,0 +1,712 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+/* Bug report URL. */
+#define BUG_REPORT_URL ""
+
+/* Relative directory for resource files */
+#define CLANG_RESOURCE_DIR ""
+
+/* 32 bit multilib directory. */
+#define CXX_INCLUDE_32BIT_DIR ""
+
+/* 64 bit multilib directory. */
+#define CXX_INCLUDE_64BIT_DIR ""
+
+/* Arch the libstdc++ headers. */
+#define CXX_INCLUDE_ARCH ""
+
+/* Directory with the libstdc++ headers. */
+#define CXX_INCLUDE_ROOT ""
+
+/* Directories clang will search for headers */
+#define C_INCLUDE_DIRS ""
+
+/* Define if CBE is enabled for printf %a output */
+#define ENABLE_CBE_PRINTF_A 1
+
+/* Define if position independent code is enabled */
+#define ENABLE_PIC
+
+/* Define if threads enabled */
+#define ENABLE_THREADS 1
+
+/* Define if timestamp information (e.g., __DATE___) is allowed */
+#define ENABLE_TIMESTAMPS 0
+
+/* Define to 1 if you have the `argz_append' function. */
+#define HAVE_ARGZ_APPEND 1
+
+/* Define to 1 if you have the `argz_create_sep' function. */
+#define HAVE_ARGZ_CREATE_SEP 1
+
+/* Define to 1 if you have the <argz.h> header file. */
+#define HAVE_ARGZ_H 1
+
+/* Define to 1 if you have the `argz_insert' function. */
+#define HAVE_ARGZ_INSERT 1
+
+/* Define to 1 if you have the `argz_next' function. */
+#define HAVE_ARGZ_NEXT 1
+
+/* Define to 1 if you have the `argz_stringify' function. */
+#define HAVE_ARGZ_STRINGIFY 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `backtrace' function. */
+#undef HAVE_BACKTRACE
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define to 1 if you have the `ceilf' function. */
+#define HAVE_CEILF 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_CIRCO */
+
+/* Define to 1 if you have the `closedir' function. */
+#define HAVE_CLOSEDIR 1
+
+/* Define to 1 if you have the <CrashReporterClient.h> header file. */
+#undef HAVE_CRASHREPORTERCLIENT_H
+
+/* Define if __crashreporter_info__ exists. */
+#undef HAVE_CRASHREPORTER_INFO
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#define HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRERROR_S 0
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the GNU dld library. */
+#undef HAVE_DLD
+
+/* Define to 1 if you have the <dld.h> header file. */
+/* #undef HAVE_DLD_H */
+
+/* Define to 1 if you have the `dlerror' function. */
+#define HAVE_DLERROR 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define if dlopen() is available on this platform. */
+#define HAVE_DLOPEN 1
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define if the dot program is available */
+/* #undef HAVE_DOT */
+
+/* Define if the dotty program is available */
+/* #undef HAVE_DOTTY */
+
+/* Define if you have the _dyld_func_lookup function. */
+#undef HAVE_DYLD
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if the system has the type `error_t'. */
+#define HAVE_ERROR_T 1
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+/* #undef HAVE_EXECINFO_H */
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_FDP */
+
+/* Define to 1 if you have the <fenv.h> header file. */
+#define HAVE_FENV_H 1
+
+/* Define if libffi is available on this platform. */
+/* #undef HAVE_FFI_CALL */
+
+/* Define to 1 if you have the <ffi/ffi.h> header file. */
+/* #undef HAVE_FFI_FFI_H */
+
+/* Define to 1 if you have the <ffi.h> header file. */
+/* #undef HAVE_FFI_H */
+
+/* Set to 1 if the finite function is found in <ieeefp.h> */
+/* #undef HAVE_FINITE_IN_IEEEFP_H */
+
+/* Define to 1 if you have the `floorf' function. */
+#define HAVE_FLOORF 1
+
+/* Define to 1 if you have the `fmodf' function. */
+#define HAVE_FMODF 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have the `getrusage' function. */
+#define HAVE_GETRUSAGE 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if the Graphviz program is available */
+#undef HAVE_GRAPHVIZ
+
+/* Define if the gv program is available */
+/* #undef HAVE_GV */
+
+/* Define to 1 if you have the `index' function. */
+#define HAVE_INDEX 1
+
+/* Define to 1 if the system has the type `int64_t'. */
+#define HAVE_INT64_T 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `isatty' function. */
+#define HAVE_ISATTY 1
+
+/* Set to 1 if the isinf function is found in <cmath> */
+/* #undef HAVE_ISINF_IN_CMATH */
+
+/* Set to 1 if the isinf function is found in <math.h> */
+#define HAVE_ISINF_IN_MATH_H 1
+
+/* Set to 1 if the isnan function is found in <cmath> */
+/* #undef HAVE_ISNAN_IN_CMATH */
+
+/* Set to 1 if the isnan function is found in <math.h> */
+#define HAVE_ISNAN_IN_MATH_H 1
+
+/* Define if you have the libdl library or equivalent. */
+#define HAVE_LIBDL 1
+
+/* Define to 1 if you have the `imagehlp' library (-limagehlp). */
+/* #undef HAVE_LIBIMAGEHLP */
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `psapi' library (-lpsapi). */
+/* #undef HAVE_LIBPSAPI */
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#define HAVE_LIBPTHREAD 1
+
+/* Define to 1 if you have the `udis86' library (-ludis86). */
+#undef HAVE_LIBUDIS86
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you can use -Wl,-export-dynamic. */
+#define HAVE_LINK_EXPORT_DYNAMIC 1
+
+/* Define to 1 if you have the <link.h> header file. */
+#define HAVE_LINK_H 1
+
+/* Define if you can use -Wl,-R. to pass -R. to the linker, in order to add
+ the current directory to the dynamic linker search path. */
+#undef HAVE_LINK_R
+
+/* Define to 1 if you have the `longjmp' function. */
+#define HAVE_LONGJMP 1
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+/* #undef HAVE_MACH_MACH_H */
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+/* #undef HAVE_MACH_O_DYLD_H */
+
+/* Define if mallinfo() is available on this platform. */
+/* #undef HAVE_MALLINFO */
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the <malloc/malloc.h> header file. */
+/* #undef HAVE_MALLOC_MALLOC_H */
+
+/* Define to 1 if you have the `malloc_zone_statistics' function. */
+/* #undef HAVE_MALLOC_ZONE_STATISTICS */
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkdtemp' function. */
+#define HAVE_MKDTEMP 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the `mktemp' function. */
+#define HAVE_MKTEMP 1
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define if mmap() uses MAP_ANONYMOUS to map anonymous pages, or undefine if
+ it uses MAP_ANON */
+#undef HAVE_MMAP_ANONYMOUS
+
+/* Define if mmap() can map files into memory */
+#undef HAVE_MMAP_FILE
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the `nearbyintf' function. */
+#define HAVE_NEARBYINTF 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_NEATO */
+
+/* Define to 1 if you have the `opendir' function. */
+#define HAVE_OPENDIR 1
+
+/* Define to 1 if you have the `posix_spawn' function. */
+/* #undef HAVE_POSIX_SPAWN */
+
+/* Define to 1 if you have the `powf' function. */
+/* #undef HAVE_POWF */
+
+/* Define if libtool can extract symbol lists from object files. */
+#undef HAVE_PRELOADED_SYMBOLS
+
+/* Define to have the %a format string */
+#undef HAVE_PRINTF_A
+
+/* Have pthread_getspecific */
+#define HAVE_PTHREAD_GETSPECIFIC 1
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#define HAVE_PTHREAD_H 1
+
+/* Have pthread_mutex_lock */
+#define HAVE_PTHREAD_MUTEX_LOCK 1
+
+/* Have pthread_rwlock_init */
+#define HAVE_PTHREAD_RWLOCK_INIT 1
+
+/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
+#define HAVE_RAND48 1
+
+/* Define to 1 if you have the `readdir' function. */
+#define HAVE_READDIR 1
+
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
+/* Define to 1 if you have the `rindex' function. */
+#define HAVE_RINDEX 1
+
+/* Define to 1 if you have the `rintf' function. */
+#undef HAVE_RINTF
+
+/* Define to 1 if you have the `round' function. */
+/* #undef HAVE_ROUND */
+
+/* Define to 1 if you have the `roundf' function. */
+#undef HAVE_ROUNDF
+
+/* Define to 1 if you have the `sbrk' function. */
+/* #undef HAVE_SBRK */
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the `setjmp' function. */
+#define HAVE_SETJMP 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define if you have the shl_load function. */
+#undef HAVE_SHL_LOAD
+
+/* Define to 1 if you have the `siglongjmp' function. */
+#define HAVE_SIGLONGJMP 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+/* #undef HAVE_SIGNAL_H */
+
+/* Define to 1 if you have the `sigsetjmp' function. */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Set to 1 if the std::isinf function is found in <cmath> */
+#undef HAVE_STD_ISINF_IN_CMATH
+
+/* Set to 1 if the std::isnan function is found in <cmath> */
+#undef HAVE_STD_ISNAN_IN_CMATH
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strcmp' function. */
+#define HAVE_STRCMP 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strrchr' function. */
+#define HAVE_STRRCHR 1
+
+/* Define to 1 if you have the `strtof' function. */
+/* #undef HAVE_STRTOF */
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the `strtoq' function. */
+#define HAVE_STRTOQ 1
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#define HAVE_SYS_DIR_H 1
+
+/* Define to 1 if you have the <sys/dl.h> header file. */
+/* #undef HAVE_SYS_DL_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define if the neat program is available */
+/* #undef HAVE_TWOPI */
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#define HAVE_UINT64_T 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if the system has the type `u_int64_t'. */
+#define HAVE_U_INT64_T 1
+
+/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
+/* #undef HAVE_VALGRIND_VALGRIND_H */
+
+/* Define to 1 if you have the <windows.h> header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the `writev' function. */
+#define HAVE_WRITEV 1
+
+/* Define if the xdot.py program is available */
+/* #undef HAVE_XDOT_PY */
+
+/* Have host's _alloca */
+/* #undef HAVE__ALLOCA */
+
+/* Have host's __alloca */
+/* #undef HAVE___ALLOCA */
+
+/* Have host's __ashldi3 */
+/* #undef HAVE___ASHLDI3 */
+
+/* Have host's __ashrdi3 */
+/* #undef HAVE___ASHRDI3 */
+
+/* Have host's __chkstk */
+/* #undef HAVE___CHKSTK */
+
+/* Have host's __cmpdi2 */
+/* #undef HAVE___CMPDI2 */
+
+/* Have host's __divdi3 */
+/* #undef HAVE___DIVDI3 */
+
+/* Define to 1 if you have the `__dso_handle' function. */
+#undef HAVE___DSO_HANDLE
+
+/* Have host's __fixdfdi */
+/* #undef HAVE___FIXDFDI */
+
+/* Have host's __fixsfdi */
+/* #undef HAVE___FIXSFDI */
+
+/* Have host's __floatdidf */
+/* #undef HAVE___FLOATDIDF */
+
+/* Have host's __lshrdi3 */
+/* #undef HAVE___LSHRDI3 */
+
+/* Have host's __main */
+/* #undef HAVE___MAIN */
+
+/* Have host's __moddi3 */
+/* #undef HAVE___MODDI3 */
+
+/* Have host's __udivdi3 */
+/* #undef HAVE___UDIVDI3 */
+
+/* Have host's __umoddi3 */
+/* #undef HAVE___UMODDI3 */
+
+/* Have host's ___chkstk */
+/* #undef HAVE____CHKSTK */
+
+/* Linker version detected at compile time. */
+#undef HOST_LINK_VERSION
+
+/* Installation directory for binary executables */
+/* #undef LLVM_BINDIR */
+
+/* Time at which LLVM was configured */
+/* #undef LLVM_CONFIGTIME */
+
+/* Installation directory for data files */
+/* #undef LLVM_DATADIR */
+
+/* Installation directory for documentation */
+/* #undef LLVM_DOCSDIR */
+
+/* Installation directory for config files */
+/* #undef LLVM_ETCDIR */
+
+/* Has gcc/MSVC atomic intrinsics */
+#define LLVM_HAS_ATOMICS 1
+
+/* Host triple we were built on */
+#define LLVM_HOSTTRIPLE "i686-pc-linux-gnu"
+
+/* Installation directory for include files */
+/* #undef LLVM_INCLUDEDIR */
+
+/* Installation directory for .info files */
+/* #undef LLVM_INFODIR */
+
+/* Installation directory for libraries */
+/* #undef LLVM_LIBDIR */
+
+/* Installation directory for man pages */
+/* #undef LLVM_MANDIR */
+
+/* LLVM architecture name for the native architecture, if available */
+#define LLVM_NATIVE_ARCH X86
+
+/* LLVM name for the native AsmParser init function, if available */
+/* #undef LLVM_NATIVE_ASMPARSER */
+
+/* LLVM name for the native AsmPrinter init function, if available */
+#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter
+
+/* LLVM name for the native Target init function, if available */
+#define LLVM_NATIVE_TARGET LLVMInitializeX86Target
+
+/* LLVM name for the native TargetInfo init function, if available */
+#define LLVM_NATIVE_TARGETINFO LLVMInitializeX86TargetInfo
+
+/* LLVM name for the native target MC init function, if available */
+#define LLVM_NATIVE_TARGETMC LLVMInitializeX86TargetMC
+
+/* Define if this is Unixish platform */
+#define LLVM_ON_UNIX 1
+
+/* Define if this is Win32ish platform */
+/* #undef LLVM_ON_WIN32 */
+
+/* Define to path to circo program if found or 'echo circo' otherwise */
+/* #undef LLVM_PATH_CIRCO */
+
+/* Define to path to dot program if found or 'echo dot' otherwise */
+/* #undef LLVM_PATH_DOT */
+
+/* Define to path to dotty program if found or 'echo dotty' otherwise */
+/* #undef LLVM_PATH_DOTTY */
+
+/* Define to path to fdp program if found or 'echo fdp' otherwise */
+/* #undef LLVM_PATH_FDP */
+
+/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
+/* #undef LLVM_PATH_GRAPHVIZ */
+
+/* Define to path to gv program if found or 'echo gv' otherwise */
+/* #undef LLVM_PATH_GV */
+
+/* Define to path to neato program if found or 'echo neato' otherwise */
+/* #undef LLVM_PATH_NEATO */
+
+/* Define to path to twopi program if found or 'echo twopi' otherwise */
+/* #undef LLVM_PATH_TWOPI */
+
+/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */
+/* #undef LLVM_PATH_XDOT_PY */
+
+/* Installation prefix directory */
+#define LLVM_PREFIX "/usr/local"
+
+/* Define if the OS needs help to load dependent libraries for dlopen(). */
+/* #undef LTDL_DLOPEN_DEPLIBS */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LTDL_OBJDIR
+
+/* Define to the name of the environment variable that determines the dynamic
+ library search path. */
+#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH"
+
+/* Define to the extension used for shared libraries, say, ".so". */
+#define LTDL_SHLIB_EXT ".so"
+
+/* Define to the system default library search path. */
+/* #undef LTDL_SYSSEARCHPATH */
+
+/* Define if /dev/zero should be used when mapping RWX memory, or undefine if
+ its not necessary */
+#undef NEED_DEV_ZERO_FOR_MMAP
+
+/* Define if dlsym() requires a leading underscore in symbol names. */
+#undef NEED_USCORE
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "llvm"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "llvm 3.0"
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "3.0"
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Define if we have the oprofile JIT-support library */
+#undef USE_OPROFILE
+
+/* Define if use udis86 library */
+#undef USE_UDIS86
+
+/* Type of 1st arg on ELM Callback */
+/* #undef WIN32_ELMCB_PCSTR */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to a type to use for `error_t' if it is not otherwise available. */
+/* #undef error_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to a function replacing strtoll */
+/* #undef strtoll */
+
+/* Define to a function implementing strtoull */
+/* #undef strtoull */
+
+/* Define to a function implementing stricmp */
+/* #undef stricmp */
+
+/* Define to a function implementing strdup */
+/* #undef strdup */
+
+/* Define to 1 if you have the `_chsize_s' function. */
+/* #undef HAVE__CHSIZE_S */
+
+/* Added by Kevin -- Maximum path length */
+#define MAXPATHLEN 2024
+
+#endif
diff --git a/third_party/LLVM/include-fuchsia/llvm/Config/llvm-config.h b/third_party/LLVM/include-fuchsia/llvm/Config/llvm-config.h
new file mode 100644
index 0000000..11e4e5c
--- /dev/null
+++ b/third_party/LLVM/include-fuchsia/llvm/Config/llvm-config.h
@@ -0,0 +1,106 @@
+/*===-- llvm/config/llvm-config.h - llvm configure variable -------*- C -*-===*/
+/* */
+/* The LLVM Compiler Infrastructure */
+/* */
+/* This file is distributed under the University of Illinois Open Source */
+/* License. See LICENSE.TXT for details. */
+/* */
+/*===----------------------------------------------------------------------===*/
+
+/* This file enumerates all of the llvm variables from configure so that
+ they can be in exported headers and won't override package specific
+ directives. This is a C file so we can include it in the llvm-c headers. */
+
+/* To avoid multiple inclusions of these variables when we include the exported
+ headers and config.h, conditionally include these. */
+/* TODO: This is a bit of a hack. */
+#ifndef CONFIG_H
+
+/* Installation directory for binary executables */
+/* #undef LLVM_BINDIR */
+
+/* Time at which LLVM was configured */
+/* #undef LLVM_CONFIGTIME */
+
+/* Installation directory for data files */
+/* #undef LLVM_DATADIR */
+
+/* Installation directory for documentation */
+/* #undef LLVM_DOCSDIR */
+
+/* Installation directory for config files */
+/* #undef LLVM_ETCDIR */
+
+/* Has gcc/MSVC atomic intrinsics */
+#define LLVM_HAS_ATOMICS 1
+
+/* Host triple we were built on */
+#define LLVM_HOSTTRIPLE "i686-pc-linux-gnu"
+
+/* Installation directory for include files */
+/* #undef LLVM_INCLUDEDIR */
+
+/* Installation directory for .info files */
+/* #undef LLVM_INFODIR */
+
+/* Installation directory for libraries */
+/* #undef LLVM_LIBDIR */
+
+/* Installation directory for man pages */
+/* #undef LLVM_MANDIR */
+
+/* LLVM architecture name for the native architecture, if available */
+#define LLVM_NATIVE_ARCH X86
+
+/* LLVM name for the native AsmParser init function, if available */
+/* #undef LLVM_NATIVE_ASMPARSER */
+
+/* LLVM name for the native AsmPrinter init function, if available */
+#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter
+
+/* LLVM name for the native Target init function, if available */
+#define LLVM_NATIVE_TARGET LLVMInitializeX86Target
+
+/* LLVM name for the native TargetInfo init function, if available */
+#define LLVM_NATIVE_TARGETINFO LLVMInitializeX86TargetInfo
+
+/* LLVM name for the native target MC init function, if available */
+#define LLVM_NATIVE_TARGETMC LLVMInitializeX86TargetMC
+
+/* Define if this is Unixish platform */
+#define LLVM_ON_UNIX 1
+
+/* Define if this is Win32ish platform */
+/* #undef LLVM_ON_WIN32 */
+
+/* Define to path to circo program if found or 'echo circo' otherwise */
+/* #undef LLVM_PATH_CIRCO */
+
+/* Define to path to dot program if found or 'echo dot' otherwise */
+/* #undef LLVM_PATH_DOT */
+
+/* Define to path to dotty program if found or 'echo dotty' otherwise */
+/* #undef LLVM_PATH_DOTTY */
+
+/* Define to path to fdp program if found or 'echo fdp' otherwise */
+/* #undef LLVM_PATH_FDP */
+
+/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
+/* #undef LLVM_PATH_GRAPHVIZ */
+
+/* Define to path to gv program if found or 'echo gv' otherwise */
+/* #undef LLVM_PATH_GV */
+
+/* Define to path to neato program if found or 'echo neato' otherwise */
+/* #undef LLVM_PATH_NEATO */
+
+/* Define to path to twopi program if found or 'echo twopi' otherwise */
+/* #undef LLVM_PATH_TWOPI */
+
+/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */
+/* #undef LLVM_PATH_XDOT_PY */
+
+/* Installation prefix directory */
+#define LLVM_PREFIX "/usr/local"
+
+#endif
\ No newline at end of file
diff --git a/third_party/LLVM/include-fuchsia/llvm/Support/DataTypes.h b/third_party/LLVM/include-fuchsia/llvm/Support/DataTypes.h
new file mode 100644
index 0000000..180c4b9
--- /dev/null
+++ b/third_party/LLVM/include-fuchsia/llvm/Support/DataTypes.h
@@ -0,0 +1,197 @@
+/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file contains definitions to figure out the size of _HOST_ data types.*|
+|* This file is important because different host OS's define different macros,*|
+|* which makes portability tough. This file exports the following *|
+|* definitions: *|
+|* *|
+|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
+|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
+|* *|
+|* No library is required when using these functions. *|
+|* *|
+|*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
+
+/* Please keep this file in sync with DataTypes.h.in */
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_UINT64_T 1
+#define HAVE_U_INT64_T 1
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#ifndef _MSC_VER
+
+/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+ being defined. We would define it here, but in order to prevent Bad Things
+ happening when system headers or C++ STL headers include stdint.h before we
+ define it here, we define it on the g++ command line (in Makefile.rules). */
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#endif
+
+#if !defined(__STDC_CONSTANT_MACROS)
+# error "Must #define __STDC_CONSTANT_MACROS before " \
+ "#including Support/DataTypes.h"
+#endif
+
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/Support/AIXDataTypesFix.h"
+#endif
+
+/* Handle incorrect definition of uint64_t as u_int64_t */
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+#else /* _MSC_VER */
+/* Visual C++ doesn't provide standard integer headers, but it does provide
+ built-in data types. */
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed int ssize_t;
+#ifndef INT8_MAX
+# define INT8_MAX 127
+#endif
+#ifndef INT8_MIN
+# define INT8_MIN -128
+#endif
+#ifndef UINT8_MAX
+# define UINT8_MAX 255
+#endif
+#ifndef INT16_MAX
+# define INT16_MAX 32767
+#endif
+#ifndef INT16_MIN
+# define INT16_MIN -32768
+#endif
+#ifndef UINT16_MAX
+# define UINT16_MAX 65535
+#endif
+#ifndef INT32_MAX
+# define INT32_MAX 2147483647
+#endif
+#ifndef INT32_MIN
+/* MSC treats -2147483648 as -(2147483648U). */
+# define INT32_MIN (-INT32_MAX - 1)
+#endif
+#ifndef UINT32_MAX
+# define UINT32_MAX 4294967295U
+#endif
+/* Certain compatibility updates to VC++ introduce the `cstdint'
+ * header, which defines the INT*_C macros. On default installs they
+ * are absent. */
+#ifndef INT8_C
+# define INT8_C(C) C##i8
+#endif
+#ifndef UINT8_C
+# define UINT8_C(C) C##ui8
+#endif
+#ifndef INT16_C
+# define INT16_C(C) C##i16
+#endif
+#ifndef UINT16_C
+# define UINT16_C(C) C##ui16
+#endif
+#ifndef INT32_C
+# define INT32_C(C) C##i32
+#endif
+#ifndef UINT32_C
+# define UINT32_C(C) C##ui32
+#endif
+#ifndef INT64_C
+# define INT64_C(C) C##i64
+#endif
+#ifndef UINT64_C
+# define UINT64_C(C) C##ui64
+#endif
+
+#ifndef PRIx64
+# define PRIx64 "I64x"
+#endif
+
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
\ No newline at end of file
diff --git a/third_party/LLVM/include/llvm/intrinsics_gen.vcxproj b/third_party/LLVM/include/llvm/intrinsics_gen.vcxproj
index aa49160..f53a817 100644
--- a/third_party/LLVM/include/llvm/intrinsics_gen.vcxproj
+++ b/third_party/LLVM/include/llvm/intrinsics_gen.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,43 +31,44 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>intrinsics_gen</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Analysis/LLVMAnalysis.vcxproj b/third_party/LLVM/lib/Analysis/LLVMAnalysis.vcxproj
index 5cb2ae2..b5349c1 100644
--- a/third_party/LLVM/lib/Analysis/LLVMAnalysis.vcxproj
+++ b/third_party/LLVM/lib/Analysis/LLVMAnalysis.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMAnalysis</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/CodeGen/LLVMCodeGen.vcxproj b/third_party/LLVM/lib/CodeGen/LLVMCodeGen.vcxproj
index 2e09532..ce7ffa3 100644
--- a/third_party/LLVM/lib/CodeGen/LLVMCodeGen.vcxproj
+++ b/third_party/LLVM/lib/CodeGen/LLVMCodeGen.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMCodeGen</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/CodeGen/SelectionDAG/LLVMSelectionDAG.vcxproj b/third_party/LLVM/lib/CodeGen/SelectionDAG/LLVMSelectionDAG.vcxproj
index d3ad90a..1098f13 100644
--- a/third_party/LLVM/lib/CodeGen/SelectionDAG/LLVMSelectionDAG.vcxproj
+++ b/third_party/LLVM/lib/CodeGen/SelectionDAG/LLVMSelectionDAG.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMSelectionDAG</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/ExecutionEngine/JIT/LLVMJIT.vcxproj b/third_party/LLVM/lib/ExecutionEngine/JIT/LLVMJIT.vcxproj
index f2934b0..735fc9e 100644
--- a/third_party/LLVM/lib/ExecutionEngine/JIT/LLVMJIT.vcxproj
+++ b/third_party/LLVM/lib/ExecutionEngine/JIT/LLVMJIT.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMJIT</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/ExecutionEngine/LLVMExecutionEngine.vcxproj b/third_party/LLVM/lib/ExecutionEngine/LLVMExecutionEngine.vcxproj
index 91a01a3..54a4ae5 100644
--- a/third_party/LLVM/lib/ExecutionEngine/LLVMExecutionEngine.vcxproj
+++ b/third_party/LLVM/lib/ExecutionEngine/LLVMExecutionEngine.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMExecutionEngine</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/MC/LLVMMC.vcxproj b/third_party/LLVM/lib/MC/LLVMMC.vcxproj
index 8c5e86b..41a20fd 100644
--- a/third_party/LLVM/lib/MC/LLVMMC.vcxproj
+++ b/third_party/LLVM/lib/MC/LLVMMC.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMMC</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Support/LLVMSupport.vcxproj b/third_party/LLVM/lib/Support/LLVMSupport.vcxproj
index 8004f5a..d52d9a8 100644
--- a/third_party/LLVM/lib/Support/LLVMSupport.vcxproj
+++ b/third_party/LLVM/lib/Support/LLVMSupport.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMSupport</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Support/Mutex.cpp b/third_party/LLVM/lib/Support/Mutex.cpp
index 8874e94..acc011f 100644
--- a/third_party/LLVM/lib/Support/Mutex.cpp
+++ b/third_party/LLVM/lib/Support/Mutex.cpp
@@ -75,7 +75,7 @@
errorcode = pthread_mutexattr_settype(&attr, kind);
assert(errorcode == 0);
-#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__)
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__Fuchsia__)
// Make it a process local mutex
errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
assert(errorcode == 0);
diff --git a/third_party/LLVM/lib/Support/Unix/Process.inc b/third_party/LLVM/lib/Support/Unix/Process.inc
index bf81969..27aaa39 100644
--- a/third_party/LLVM/lib/Support/Unix/Process.inc
+++ b/third_party/LLVM/lib/Support/Unix/Process.inc
@@ -77,6 +77,8 @@
return EndOfMemory - StartOfMemory;
else
return 0;
+#elif defined(__Fuchsia__)
+ return 0;
#else
#warning Cannot get malloc info on this platform
return 0;
diff --git a/third_party/LLVM/lib/TableGen/LLVMTableGen.vcxproj b/third_party/LLVM/lib/TableGen/LLVMTableGen.vcxproj
index a7a7b9a..f7bd0a9 100644
--- a/third_party/LLVM/lib/TableGen/LLVMTableGen.vcxproj
+++ b/third_party/LLVM/lib/TableGen/LLVMTableGen.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMTableGen</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Target/LLVMTarget.vcxproj b/third_party/LLVM/lib/Target/LLVMTarget.vcxproj
index c3d28c2..f552d4e 100644
--- a/third_party/LLVM/lib/Target/LLVMTarget.vcxproj
+++ b/third_party/LLVM/lib/Target/LLVMTarget.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMTarget</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Target/X86/InstPrinter/LLVMX86AsmPrinter.vcxproj b/third_party/LLVM/lib/Target/X86/InstPrinter/LLVMX86AsmPrinter.vcxproj
index a31a7b9..f2d67ad 100644
--- a/third_party/LLVM/lib/Target/X86/InstPrinter/LLVMX86AsmPrinter.vcxproj
+++ b/third_party/LLVM/lib/Target/X86/InstPrinter/LLVMX86AsmPrinter.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMX86AsmPrinter</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Target/X86/LLVMX86CodeGen.vcxproj b/third_party/LLVM/lib/Target/X86/LLVMX86CodeGen.vcxproj
index ff36f1c..4030687 100644
--- a/third_party/LLVM/lib/Target/X86/LLVMX86CodeGen.vcxproj
+++ b/third_party/LLVM/lib/Target/X86/LLVMX86CodeGen.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMX86CodeGen</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Target/X86/MCTargetDesc/LLVMX86Desc.vcxproj b/third_party/LLVM/lib/Target/X86/MCTargetDesc/LLVMX86Desc.vcxproj
index 88d1c7b..1a19a97 100644
--- a/third_party/LLVM/lib/Target/X86/MCTargetDesc/LLVMX86Desc.vcxproj
+++ b/third_party/LLVM/lib/Target/X86/MCTargetDesc/LLVMX86Desc.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMX86Desc</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Target/X86/TargetInfo/LLVMX86Info.vcxproj b/third_party/LLVM/lib/Target/X86/TargetInfo/LLVMX86Info.vcxproj
index a120eb5..c8dd335 100644
--- a/third_party/LLVM/lib/Target/X86/TargetInfo/LLVMX86Info.vcxproj
+++ b/third_party/LLVM/lib/Target/X86/TargetInfo/LLVMX86Info.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMX86Info</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Target/X86/Utils/LLVMX86Utils.vcxproj b/third_party/LLVM/lib/Target/X86/Utils/LLVMX86Utils.vcxproj
index 05873eb..df78cee 100644
--- a/third_party/LLVM/lib/Target/X86/Utils/LLVMX86Utils.vcxproj
+++ b/third_party/LLVM/lib/Target/X86/Utils/LLVMX86Utils.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMX86Utils</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Target/X86/X86CommonTableGen.vcxproj b/third_party/LLVM/lib/Target/X86/X86CommonTableGen.vcxproj
index 6abfa37..0f076d4 100644
--- a/third_party/LLVM/lib/Target/X86/X86CommonTableGen.vcxproj
+++ b/third_party/LLVM/lib/Target/X86/X86CommonTableGen.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,43 +31,44 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>X86CommonTableGen</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>Utility</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Transforms/InstCombine/LLVMInstCombine.vcxproj b/third_party/LLVM/lib/Transforms/InstCombine/LLVMInstCombine.vcxproj
index 133e494..baa3f10 100644
--- a/third_party/LLVM/lib/Transforms/InstCombine/LLVMInstCombine.vcxproj
+++ b/third_party/LLVM/lib/Transforms/InstCombine/LLVMInstCombine.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMInstCombine</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Transforms/Scalar/LLVMScalarOpts.vcxproj b/third_party/LLVM/lib/Transforms/Scalar/LLVMScalarOpts.vcxproj
index 774cfd2..c480d23 100644
--- a/third_party/LLVM/lib/Transforms/Scalar/LLVMScalarOpts.vcxproj
+++ b/third_party/LLVM/lib/Transforms/Scalar/LLVMScalarOpts.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMScalarOpts</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/Transforms/Utils/LLVMTransformUtils.vcxproj b/third_party/LLVM/lib/Transforms/Utils/LLVMTransformUtils.vcxproj
index 2b45eaf..4f2df89 100644
--- a/third_party/LLVM/lib/Transforms/Utils/LLVMTransformUtils.vcxproj
+++ b/third_party/LLVM/lib/Transforms/Utils/LLVMTransformUtils.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMTransformUtils</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/lib/VMCore/LLVMCore.vcxproj b/third_party/LLVM/lib/VMCore/LLVMCore.vcxproj
index e9c7424..681dfbe 100644
--- a/third_party/LLVM/lib/VMCore/LLVMCore.vcxproj
+++ b/third_party/LLVM/lib/VMCore/LLVMCore.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,47 +31,48 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>LLVMCore</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/LLVM/utils/TableGen/llvm-tblgen.vcxproj b/third_party/LLVM/utils/TableGen/llvm-tblgen.vcxproj
index 50a548c..0c21d51 100644
--- a/third_party/LLVM/utils/TableGen/llvm-tblgen.vcxproj
+++ b/third_party/LLVM/utils/TableGen/llvm-tblgen.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -31,43 +31,44 @@
<Keyword>Win32Proj</Keyword>
<Platform>Win32</Platform>
<ProjectName>llvm-tblgen</ProjectName>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>NotSet</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/PowerVR_SDK/Examples/Advanced/ChameleonMan/OGLES2/Build/WindowsVC2010/OGLES2ChameleonMan.vcxproj b/third_party/PowerVR_SDK/Examples/Advanced/ChameleonMan/OGLES2/Build/WindowsVC2010/OGLES2ChameleonMan.vcxproj
index 8b408a9..9d6dadc 100644
--- a/third_party/PowerVR_SDK/Examples/Advanced/ChameleonMan/OGLES2/Build/WindowsVC2010/OGLES2ChameleonMan.vcxproj
+++ b/third_party/PowerVR_SDK/Examples/Advanced/ChameleonMan/OGLES2/Build/WindowsVC2010/OGLES2ChameleonMan.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,33 +21,34 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{9CF4408B-9B08-481F-95DA-3DF0846DABE4}</ProjectGuid>
<RootNamespace>OGLES2ChameleonMan</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/PowerVR_SDK/Examples/Beginner/01_HelloAPI/OGLES2/Build/WindowsVC2010/OGLES2HelloAPI.vcxproj b/third_party/PowerVR_SDK/Examples/Beginner/01_HelloAPI/OGLES2/Build/WindowsVC2010/OGLES2HelloAPI.vcxproj
index 803dd10..e4d373b 100644
--- a/third_party/PowerVR_SDK/Examples/Beginner/01_HelloAPI/OGLES2/Build/WindowsVC2010/OGLES2HelloAPI.vcxproj
+++ b/third_party/PowerVR_SDK/Examples/Beginner/01_HelloAPI/OGLES2/Build/WindowsVC2010/OGLES2HelloAPI.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,33 +21,34 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{9DAFEE32-19F6-4410-AA09-2B564FB86F62}</ProjectGuid>
<RootNamespace>OGLES2HelloAPI</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/PowerVR_SDK/Examples/Beginner/04_BasicTnL/OGLES/Build/WindowsVC2010/OGLESBasicTnL.vcxproj b/third_party/PowerVR_SDK/Examples/Beginner/04_BasicTnL/OGLES/Build/WindowsVC2010/OGLESBasicTnL.vcxproj
index 7612825..1a977d2 100644
--- a/third_party/PowerVR_SDK/Examples/Beginner/04_BasicTnL/OGLES/Build/WindowsVC2010/OGLESBasicTnL.vcxproj
+++ b/third_party/PowerVR_SDK/Examples/Beginner/04_BasicTnL/OGLES/Build/WindowsVC2010/OGLESBasicTnL.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,33 +21,34 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{AB1EB229-D86C-41B3-8E20-7A7E1FF5DDF5}</ProjectGuid>
<RootNamespace>OGLESBasicTnL</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/PowerVR_SDK/Examples/Intermediate/ColourGrading/OGLES3/Build/WindowsVC2010/OGLES3ColourGrading.vcxproj b/third_party/PowerVR_SDK/Examples/Intermediate/ColourGrading/OGLES3/Build/WindowsVC2010/OGLES3ColourGrading.vcxproj
index 2ed904f..363a529 100644
--- a/third_party/PowerVR_SDK/Examples/Intermediate/ColourGrading/OGLES3/Build/WindowsVC2010/OGLES3ColourGrading.vcxproj
+++ b/third_party/PowerVR_SDK/Examples/Intermediate/ColourGrading/OGLES3/Build/WindowsVC2010/OGLES3ColourGrading.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,33 +21,34 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{2EA5725B-25DA-44E2-B71E-BD9F55F3C2E2}</ProjectGuid>
<RootNamespace>OGLES3ColourGrading</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/PowerVR_SDK/Examples/Intermediate/DisplacementMap/OGLES2/Build/WindowsVC2010/OGLES2DisplacementMap.vcxproj b/third_party/PowerVR_SDK/Examples/Intermediate/DisplacementMap/OGLES2/Build/WindowsVC2010/OGLES2DisplacementMap.vcxproj
index 7de10d1..908b4dc 100644
--- a/third_party/PowerVR_SDK/Examples/Intermediate/DisplacementMap/OGLES2/Build/WindowsVC2010/OGLES2DisplacementMap.vcxproj
+++ b/third_party/PowerVR_SDK/Examples/Intermediate/DisplacementMap/OGLES2/Build/WindowsVC2010/OGLES2DisplacementMap.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -21,33 +21,34 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{04FC5430-3F1B-42A2-A18A-D8BB7E5B2733}</ProjectGuid>
<RootNamespace>OGLES2DisplacementMap</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/PowerVR_SDK/Tools/OGLES2/Build/WindowsVC2010/OGLES2Tools.vcxproj b/third_party/PowerVR_SDK/Tools/OGLES2/Build/WindowsVC2010/OGLES2Tools.vcxproj
index 7c8d131..df193fa 100644
--- a/third_party/PowerVR_SDK/Tools/OGLES2/Build/WindowsVC2010/OGLES2Tools.vcxproj
+++ b/third_party/PowerVR_SDK/Tools/OGLES2/Build/WindowsVC2010/OGLES2Tools.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -22,29 +22,30 @@
<ProjectGuid>{09ABE661-9BC0-4152-A820-1FB0522CAC01}</ProjectGuid>
<RootNamespace>OGLES2Tools</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/PowerVR_SDK/Tools/OGLES3/Build/WindowsVC2010/OGLES3Tools.vcxproj b/third_party/PowerVR_SDK/Tools/OGLES3/Build/WindowsVC2010/OGLES3Tools.vcxproj
index dabdf51..8c190f7 100644
--- a/third_party/PowerVR_SDK/Tools/OGLES3/Build/WindowsVC2010/OGLES3Tools.vcxproj
+++ b/third_party/PowerVR_SDK/Tools/OGLES3/Build/WindowsVC2010/OGLES3Tools.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -22,29 +22,30 @@
<ProjectGuid>{9088FC9E-9843-4E0D-85D0-1B657AFC480A}</ProjectGuid>
<RootNamespace>OGLES3Tools</RootNamespace>
<Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
diff --git a/third_party/googletest b/third_party/googletest
index ecd5308..0fe9660 160000
--- a/third_party/googletest
+++ b/third_party/googletest
@@ -1 +1 @@
-Subproject commit ecd530865cefdfa7dea58e84f6aa1b548950363d
+Subproject commit 0fe96607d85cf3a25ac40da369db62bbee2939a5
diff --git a/third_party/llvm-subzero/lib/Support/NativeFormatting.cpp b/third_party/llvm-subzero/lib/Support/NativeFormatting.cpp
index bb86891..88a07bb 100644
--- a/third_party/llvm-subzero/lib/Support/NativeFormatting.cpp
+++ b/third_party/llvm-subzero/lib/Support/NativeFormatting.cpp
@@ -14,6 +14,8 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Format.h"
+#include <float.h>
+
using namespace llvm;
template<typename T, std::size_t N>
diff --git a/third_party/subzero/codereview.settings b/third_party/subzero/codereview.settings
index 19e1584..093bbe6 100644
--- a/third_party/subzero/codereview.settings
+++ b/third_party/subzero/codereview.settings
@@ -1,10 +1,6 @@
-# This file is used by gcl to get repository specific information.
+# This file is used by git-cl to get repository specific information.
+GERRIT_HOST: True
CODE_REVIEW_SERVER: codereview.chromium.org
CC_LIST: native-client-reviews@googlegroups.com
-VIEW_VC: https://gerrit.chromium.org/gerrit/gitweb?p=native_client/pnacl-subzero.git;a=commit;h=
+VIEW_VC: https://chromium.googlesource.com/native_client/pnacl-subzero/+/
STATUS: http://nativeclient-status.appspot.com/status
-TRY_ON_UPLOAD: False
-TRYSERVER_PROJECT: nacl
-TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-nacl
-PUSH_URL_CONFIG: url.ssh://gerrit.chromium.org.pushinsteadof
-ORIGIN_URL_CONFIG: http://chromium.googlesource.com
diff --git a/third_party/subzero/src/IceAssemblerARM32.cpp b/third_party/subzero/src/IceAssemblerARM32.cpp
index 2cf09ff..4b1fcb9 100644
--- a/third_party/subzero/src/IceAssemblerARM32.cpp
+++ b/third_party/subzero/src/IceAssemblerARM32.cpp
@@ -606,6 +606,25 @@
"=pc not allowed when CC=1");
}
+enum SIMDShiftType { ST_Vshl, ST_Vshr };
+
+IValueT encodeSIMDShiftImm6(SIMDShiftType Shift, Type ElmtTy,
+ const IValueT Imm) {
+ assert(Imm > 0);
+ const SizeT MaxShift = getScalarIntBitWidth(ElmtTy);
+ assert(Imm < 2 * MaxShift);
+ assert(ElmtTy == IceType_i8 || ElmtTy == IceType_i16 ||
+ ElmtTy == IceType_i32);
+ const IValueT VshlImm = Imm - MaxShift;
+ const IValueT VshrImm = 2 * MaxShift - Imm;
+ return ((Shift == ST_Vshl) ? VshlImm : VshrImm) & (2 * MaxShift - 1);
+}
+
+IValueT encodeSIMDShiftImm6(SIMDShiftType Shift, Type ElmtTy,
+ const ConstantInteger32 *Imm6) {
+ const IValueT Imm = Imm6->getValue();
+ return encodeSIMDShiftImm6(Shift, ElmtTy, Imm);
+}
} // end of anonymous namespace
namespace Ice {
@@ -2838,6 +2857,31 @@
emitInst(Encoding);
}
+void AssemblerARM32::vldrq(const Operand *OpQd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetInfo &TInfo) {
+ // This is a pseudo-instruction which loads 64-bit data into a quadword
+ // vector register. It is implemented by loading into the lower doubleword.
+
+ // VLDR - ARM section A8.8.333, encoding A1.
+ // vldr<c> <Dd>, [<Rn>{, #+/-<imm>}]
+ //
+ // cccc1101UD01nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
+ // iiiiiiii=abs(Imm >> 2), and U=1 if Opcode>=0.
+ constexpr const char *Vldrd = "vldrd";
+ IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vldrd));
+ assert(CondARM32::isDefined(Cond));
+ IValueT Address;
+ EncodedOperand AddressEncoding =
+ encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
+ (void)AddressEncoding;
+ assert(AddressEncoding == EncodedAsImmRegOffset);
+ IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 |
+ (encodeCondition(Cond) << kConditionShift) |
+ (getYInRegYXXXX(Dd) << 22) |
+ (getXXXXInRegYXXXX(Dd) << 12) | Address;
+ emitInst(Encoding);
+}
+
void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetInfo &TInfo) {
// VDLR - ARM section A8.8.333, encoding A2.
@@ -2893,6 +2937,38 @@
emitInst(Encoding);
}
+void AssemblerARM32::emitVMem1Op(IValueT Opcode, IValueT Dd, IValueT Rn,
+ IValueT Rm, size_t ElmtSize, IValueT Align,
+ const char *InstName) {
+ assert(Utils::IsAbsoluteUint(2, Align));
+ IValueT EncodedElmtSize;
+ switch (ElmtSize) {
+ default: {
+ std::string Buffer;
+ llvm::raw_string_ostream StrBuf(Buffer);
+ StrBuf << InstName << ": found invalid vector element size " << ElmtSize;
+ llvm::report_fatal_error(StrBuf.str());
+ }
+ case 8:
+ EncodedElmtSize = 0;
+ break;
+ case 16:
+ EncodedElmtSize = 1;
+ break;
+ case 32:
+ EncodedElmtSize = 2;
+ break;
+ case 64:
+ EncodedElmtSize = 3;
+ }
+ const IValueT Encoding =
+ Opcode | (encodeCondition(CondARM32::kNone) << kConditionShift) |
+ (getYInRegYXXXX(Dd) << 22) | (Rn << kRnShift) |
+ (getXXXXInRegYXXXX(Dd) << kRdShift) | (EncodedElmtSize << 10) |
+ (Align << 4) | Rm;
+ emitInst(Encoding);
+}
+
void AssemblerARM32::vld1qr(size_t ElmtSize, const Operand *OpQd,
const Operand *OpAddress, const TargetInfo &TInfo) {
// VLD1 (multiple single elements) - ARM section A8.8.320, encoding A1:
@@ -2915,6 +2991,36 @@
emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vld1qr);
}
+void AssemblerARM32::vld1(size_t ElmtSize, const Operand *OpQd,
+ const Operand *OpAddress, const TargetInfo &TInfo) {
+ // This is a pseudo-instruction for loading a single element of a quadword
+ // vector. For 64-bit the lower doubleword vector is loaded.
+
+ if (ElmtSize == 64) {
+ return vldrq(OpQd, OpAddress, Ice::CondARM32::AL, TInfo);
+ }
+
+ // VLD1 (single elements to one lane) - ARMv7-A/R section A8.6.308, encoding
+ // A1:
+ // VLD1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>
+ //
+ // 111101001D10nnnnddddss00aaaammmm where tttt=DRegListSize2, Dddd=Qd,
+ // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the
+ // encoding of ElmtSize.
+ constexpr const char *Vld1qr = "vld1qr";
+ const IValueT Qd = encodeQRegister(OpQd, "Qd", Vld1qr);
+ const IValueT Dd = mapQRegToDReg(Qd);
+ IValueT Address;
+ if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) !=
+ EncodedAsImmRegOffset)
+ llvm::report_fatal_error(std::string(Vld1qr) + ": malform memory address");
+ const IValueT Rn = mask(Address, kRnShift, 4);
+ constexpr IValueT Rm = RegARM32::Reg_pc;
+ constexpr IValueT Opcode = B26 | B23 | B21;
+ constexpr IValueT Align = 0; // use default alignment.
+ emitVMem1Op(Opcode, Dd, Rn, Rm, ElmtSize, Align, Vld1qr);
+}
+
bool AssemblerARM32::vmovqc(const Operand *OpQd, const ConstantInteger32 *Imm) {
// VMOV (immediate) - ARM section A8.8.320, encoding A1:
// VMOV.<dt> <Qd>, #<Imm>
@@ -3226,6 +3332,183 @@
emitSIMDqqq(VmulqiOpcode, ElmtTy, OpQd, OpQn, OpQm, Vmulqi);
}
+void AssemblerARM32::vmulh(Type ElmtTy, const Operand *OpQd,
+ const Operand *OpQn, const Operand *OpQm,
+ bool Unsigned) {
+ // Pseudo-instruction for multiplying the corresponding elements in the lower
+ // halves of two quadword vectors, and returning the high halves.
+
+ // VMULL (integer and polynomial) - ARMv7-A/R section A8.6.337, encoding A1:
+ // VMUL<c>.<dt> <Dd>, <Dn>, <Dm>
+ //
+ // 1111001U1Dssnnnndddd11o0N0M0mmmm
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vmull expects vector with integer element type");
+ assert(ElmtTy != IceType_i64 && "vmull on i64 vector not allowed");
+ constexpr const char *Vmull = "vmull";
+
+ constexpr IValueT ElmtShift = 20;
+ const IValueT ElmtSize = encodeElmtType(ElmtTy);
+ assert(Utils::IsUint(2, ElmtSize));
+
+ const IValueT VmullOpcode =
+ B25 | (Unsigned ? B24 : 0) | B23 | (B20) | B11 | B10;
+
+ const IValueT Qd = encodeQRegister(OpQd, "Qd", Vmull);
+ const IValueT Qn = encodeQRegister(OpQn, "Qn", Vmull);
+ const IValueT Qm = encodeQRegister(OpQm, "Qm", Vmull);
+
+ const IValueT Dd = mapQRegToDReg(Qd);
+ const IValueT Dn = mapQRegToDReg(Qn);
+ const IValueT Dm = mapQRegToDReg(Qm);
+
+ constexpr bool UseQRegs = false;
+ constexpr bool IsFloatTy = false;
+ emitSIMDBase(VmullOpcode | (ElmtSize << ElmtShift), Dd, Dn, Dm, UseQRegs,
+ IsFloatTy);
+
+ // Shift and narrow to obtain high halves.
+ constexpr IValueT VshrnOpcode = B25 | B23 | B11 | B4;
+ const IValueT Imm6 = encodeSIMDShiftImm6(ST_Vshr, IceType_i16, 16);
+ constexpr IValueT ImmShift = 16;
+
+ emitSIMDBase(VshrnOpcode | (Imm6 << ImmShift), Dd, 0, Dd, UseQRegs,
+ IsFloatTy);
+}
+
+void AssemblerARM32::vmlap(Type ElmtTy, const Operand *OpQd,
+ const Operand *OpQn, const Operand *OpQm) {
+ // Pseudo-instruction for multiplying the corresponding elements in the lower
+ // halves of two quadword vectors, and pairwise-adding the results.
+
+ // VMULL (integer and polynomial) - ARM section A8.8.350, encoding A1:
+ // vmull<c>.<dt> <Qd>, <Qn>, <Qm>
+ //
+ // 1111001U1Dssnnnndddd11o0N0M0mmmm
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vmull expects vector with integer element type");
+ assert(ElmtTy != IceType_i64 && "vmull on i64 vector not allowed");
+ constexpr const char *Vmull = "vmull";
+
+ constexpr IValueT ElmtShift = 20;
+ const IValueT ElmtSize = encodeElmtType(ElmtTy);
+ assert(Utils::IsUint(2, ElmtSize));
+
+ bool Unsigned = false;
+ const IValueT VmullOpcode =
+ B25 | (Unsigned ? B24 : 0) | B23 | (B20) | B11 | B10;
+
+ const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vmull));
+ const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmull));
+ const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmull));
+
+ constexpr bool UseQRegs = false;
+ constexpr bool IsFloatTy = false;
+ emitSIMDBase(VmullOpcode | (ElmtSize << ElmtShift), Dd, Dn, Dm, UseQRegs,
+ IsFloatTy);
+
+ // VPADD - ARM section A8.8.280, encoding A1:
+ // vpadd.<dt> <Dd>, <Dm>, <Dn>
+ //
+ // 111100100Dssnnnndddd1011NQM1mmmm where Ddddd=<Dd>, Mmmmm=<Dm>, and
+ // Nnnnn=<Dn> and ss is the encoding of <dt>.
+ assert(ElmtTy != IceType_i64 && "vpadd doesn't allow i64!");
+ const IValueT VpaddOpcode =
+ B25 | B11 | B9 | B8 | B4 | ((encodeElmtType(ElmtTy) + 1) << 20);
+ emitSIMDBase(VpaddOpcode, Dd, Dd, Dd + 1, UseQRegs, IsFloatTy);
+}
+
+void AssemblerARM32::vdup(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
+ IValueT Idx) {
+ // VDUP (scalar) - ARMv7-A/R section A8.6.302, encoding A1:
+ // VDUP<c>.<size> <Qd>, <Dm[x]>
+ //
+ // 111100111D11iiiiddd011000QM0mmmm where Dddd=<Qd>, Mmmmm=<Dm>, and
+ // iiii=imm4 encodes <size> and [x].
+ constexpr const char *Vdup = "vdup";
+
+ const IValueT VdupOpcode = B25 | B24 | B23 | B21 | B20 | B11 | B10;
+
+ const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vdup));
+ const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vdup));
+
+ constexpr bool UseQRegs = true;
+ constexpr bool IsFloatTy = false;
+
+ IValueT Imm4 = 0;
+ bool Lower = true;
+ switch (ElmtTy) {
+ case IceType_i8:
+ assert(Idx < 16);
+ Lower = Idx < 8;
+ Imm4 = 1 | ((Idx & 0x7) << 1);
+ break;
+ case IceType_i16:
+ assert(Idx < 8);
+ Lower = Idx < 4;
+ Imm4 = 2 | ((Idx & 0x3) << 2);
+ break;
+ case IceType_i32:
+ case IceType_f32:
+ assert(Idx < 4);
+ Lower = Idx < 2;
+ Imm4 = 4 | ((Idx & 0x1) << 3);
+ break;
+ default:
+ assert(false && "vdup only supports 8, 16, and 32-bit elements");
+ break;
+ }
+
+ emitSIMDBase(VdupOpcode, Dd, Imm4, Dn + (Lower ? 0 : 1), UseQRegs, IsFloatTy);
+}
+
+void AssemblerARM32::vzip(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm) {
+ // Pseudo-instruction which interleaves the elements of the lower halves of
+ // two quadword registers.
+
+ // Vzip - ARMv7-A/R section A8.6.410, encoding A1:
+ // VZIP<c>.<size> <Dd>, <Dm>
+ //
+ // 111100111D11ss10dddd00011QM0mmmm where Ddddd=<Dd>, Mmmmm=<Dm>, and
+ // ss=<size>
+ assert(ElmtTy != IceType_i64 && "vzip on i64 vector not allowed");
+
+ constexpr const char *Vzip = "vzip";
+ const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vzip));
+ const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vzip));
+ const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vzip));
+
+ constexpr bool UseQRegs = false;
+ constexpr bool IsFloatTy = false;
+
+ // VMOV Dd, Dm
+ // 111100100D10mmmmdddd0001MQM1mmmm
+ constexpr IValueT VmovOpcode = B25 | B21 | B8 | B4;
+
+ // Copy lower half of second source to upper half of destination.
+ emitSIMDBase(VmovOpcode, Dd + 1, Dm, Dm, UseQRegs, IsFloatTy);
+
+ // Copy lower half of first source to lower half of destination.
+ if (Dd != Dn)
+ emitSIMDBase(VmovOpcode, Dd, Dn, Dn, UseQRegs, IsFloatTy);
+
+ constexpr IValueT ElmtShift = 18;
+ const IValueT ElmtSize = encodeElmtType(ElmtTy);
+ assert(Utils::IsUint(2, ElmtSize));
+
+ if (ElmtTy != IceType_i32 && ElmtTy != IceType_f32) {
+ constexpr IValueT VzipOpcode = B25 | B24 | B23 | B21 | B20 | B17 | B8 | B7;
+ // Zip the lower and upper half of destination.
+ emitSIMDBase(VzipOpcode | (ElmtSize << ElmtShift), Dd, 0, Dd + 1, UseQRegs,
+ IsFloatTy);
+ } else {
+ constexpr IValueT VtrnOpcode = B25 | B24 | B23 | B21 | B20 | B17 | B7;
+ emitSIMDBase(VtrnOpcode | (ElmtSize << ElmtShift), Dd, 0, Dd + 1, UseQRegs,
+ IsFloatTy);
+ }
+}
+
void AssemblerARM32::vmulqf(const Operand *OpQd, const Operand *OpQn,
const Operand *OpQm) {
// VMUL (floating-point) - ARM section A8.8.351, encoding A1:
@@ -3256,6 +3539,110 @@
mapQRegToDReg(Qm), UseQRegs, IsFloat);
}
+void AssemblerARM32::vmovlq(const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm) {
+ // Pseudo-instruction to copy the first source operand and insert the lower
+ // half of the second operand into the lower half of the destination.
+
+ // VMOV (register) - ARMv7-A/R section A8.6.327, encoding A1:
+ // VMOV<c> <Dd>, <Dm>
+ //
+ // 111100111D110000ddd001011QM0mmm0 where Dddd=Qd, Mmmm=Qm, and Q=0.
+
+ constexpr const char *Vmov = "vmov";
+ const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vmov));
+ const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmov));
+ const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmov));
+
+ constexpr bool UseQRegs = false;
+ constexpr bool IsFloat = false;
+
+ const IValueT VmovOpcode = B25 | B21 | B8 | B4;
+
+ if (Dd != Dm)
+ emitSIMDBase(VmovOpcode, Dd, Dm, Dm, UseQRegs, IsFloat);
+ if (Dd + 1 != Dn + 1)
+ emitSIMDBase(VmovOpcode, Dd + 1, Dn + 1, Dn + 1, UseQRegs, IsFloat);
+}
+
+void AssemblerARM32::vmovhq(const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm) {
+ // Pseudo-instruction to copy the first source operand and insert the high
+ // half of the second operand into the high half of the destination.
+
+ // VMOV (register) - ARMv7-A/R section A8.6.327, encoding A1:
+ // VMOV<c> <Dd>, <Dm>
+ //
+ // 111100111D110000ddd001011QM0mmm0 where Dddd=Qd, Mmmm=Qm, and Q=0.
+
+ constexpr const char *Vmov = "vmov";
+ const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vmov));
+ const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmov));
+ const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmov));
+
+ constexpr bool UseQRegs = false;
+ constexpr bool IsFloat = false;
+
+ const IValueT VmovOpcode = B25 | B21 | B8 | B4;
+
+ if (Dd != Dn)
+ emitSIMDBase(VmovOpcode, Dd, Dn, Dn, UseQRegs, IsFloat);
+ if (Dd + 1 != Dm + 1)
+ emitSIMDBase(VmovOpcode, Dd + 1, Dm + 1, Dm + 1, UseQRegs, IsFloat);
+}
+
+void AssemblerARM32::vmovhlq(const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm) {
+ // Pseudo-instruction to copy the first source operand and insert the high
+ // half of the second operand into the lower half of the destination.
+
+ // VMOV (register) - ARMv7-A/R section A8.6.327, encoding A1:
+ // VMOV<c> <Dd>, <Dm>
+ //
+ // 111100111D110000ddd001011QM0mmm0 where Dddd=Qd, Mmmm=Qm, and Q=0.
+
+ constexpr const char *Vmov = "vmov";
+ const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vmov));
+ const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmov));
+ const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmov));
+
+ constexpr bool UseQRegs = false;
+ constexpr bool IsFloat = false;
+
+ const IValueT VmovOpcode = B25 | B21 | B8 | B4;
+
+ if (Dd != Dm + 1)
+ emitSIMDBase(VmovOpcode, Dd, Dm + 1, Dm + 1, UseQRegs, IsFloat);
+ if (Dd + 1 != Dn + 1)
+ emitSIMDBase(VmovOpcode, Dd + 1, Dn + 1, Dn + 1, UseQRegs, IsFloat);
+}
+
+void AssemblerARM32::vmovlhq(const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm) {
+ // Pseudo-instruction to copy the first source operand and insert the lower
+ // half of the second operand into the high half of the destination.
+
+ // VMOV (register) - ARMv7-A/R section A8.6.327, encoding A1:
+ // VMOV<c> <Dd>, <Dm>
+ //
+ // 111100111D110000ddd001011QM0mmm0 where Dddd=Qd, Mmmm=Qm, and Q=0.
+
+ constexpr const char *Vmov = "vmov";
+ const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vmov));
+ const IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", Vmov));
+ const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vmov));
+
+ constexpr bool UseQRegs = false;
+ constexpr bool IsFloat = false;
+
+ const IValueT VmovOpcode = B25 | B21 | B8 | B4;
+
+ if (Dd + 1 != Dm)
+ emitSIMDBase(VmovOpcode, Dd + 1, Dm, Dm, UseQRegs, IsFloat);
+ if (Dd != Dn)
+ emitSIMDBase(VmovOpcode, Dd, Dn, Dn, UseQRegs, IsFloat);
+}
+
void AssemblerARM32::vnegqs(Type ElmtTy, const Operand *OpQd,
const Operand *OpQm) {
// VNEG - ARM section A8.8.355, encoding A1:
@@ -3314,6 +3701,31 @@
emitInst(Encoding);
}
+void AssemblerARM32::vstrq(const Operand *OpQd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetInfo &TInfo) {
+ // This is a pseudo-instruction which stores 64-bit data into a quadword
+ // vector register. It is implemented by storing into the lower doubleword.
+
+ // VSTR - ARM section A8.8.413, encoding A1:
+ // vstr<c> <Dd>, [<Rn>{, #+/-<Imm>}]
+ //
+ // cccc1101UD00nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
+ // iiiiiiii=abs(Imm >> 2), and U=1 if Imm>=0.
+ constexpr const char *Vstrd = "vstrd";
+ IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Dd", Vstrd));
+ assert(CondARM32::isDefined(Cond));
+ IValueT Address;
+ IValueT AddressEncoding =
+ encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
+ (void)AddressEncoding;
+ assert(AddressEncoding == EncodedAsImmRegOffset);
+ IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 |
+ (encodeCondition(Cond) << kConditionShift) |
+ (getYInRegYXXXX(Dd) << 22) |
+ (getXXXXInRegYXXXX(Dd) << 12) | Address;
+ emitInst(Encoding);
+}
+
void AssemblerARM32::vstrs(const Operand *OpSd, const Operand *OpAddress,
CondARM32::Cond Cond, const TargetInfo &TInfo) {
// VSTR - ARM section A8.8.413, encoding A2:
@@ -3357,6 +3769,37 @@
emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vst1qr);
}
+void AssemblerARM32::vst1(size_t ElmtSize, const Operand *OpQd,
+ const Operand *OpAddress, const TargetInfo &TInfo) {
+
+ // This is a pseudo-instruction for storing a single element of a quadword
+ // vector. For 64-bit the lower doubleword vector is stored.
+
+ if (ElmtSize == 64) {
+ return vstrq(OpQd, OpAddress, Ice::CondARM32::AL, TInfo);
+ }
+
+ // VST1 (single element from one lane) - ARMv7-A/R section A8.6.392, encoding
+ // A1:
+ // VST1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>
+ //
+ // 111101001D00nnnnddd0ss00aaaammmm where Dddd=Qd, nnnn=Rn,
+ // aaaa=0 (use default alignment), size=ElmtSize, and ss is the
+ // encoding of ElmtSize.
+ constexpr const char *Vst1qr = "vst1qr";
+ const IValueT Qd = encodeQRegister(OpQd, "Qd", Vst1qr);
+ const IValueT Dd = mapQRegToDReg(Qd);
+ IValueT Address;
+ if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) !=
+ EncodedAsImmRegOffset)
+ llvm::report_fatal_error(std::string(Vst1qr) + ": malform memory address");
+ const IValueT Rn = mask(Address, kRnShift, 4);
+ constexpr IValueT Rm = RegARM32::Reg_pc;
+ constexpr IValueT Opcode = B26 | B23;
+ constexpr IValueT Align = 0; // use default alignment.
+ emitVMem1Op(Opcode, Dd, Rn, Rm, ElmtSize, Align, Vst1qr);
+}
+
void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn,
const Operand *OpSm, CondARM32::Cond Cond) {
// VSUB (floating-point) - ARM section A8.8.415, encoding A2:
@@ -3381,6 +3824,62 @@
emitVFPddd(Cond, VsubdOpcode, OpDd, OpDn, OpDm, Vsubd);
}
+void AssemblerARM32::vqaddqi(Type ElmtTy, const Operand *OpQd,
+ const Operand *OpQm, const Operand *OpQn) {
+ // VQADD (integer) - ARM section A8.6.369, encoding A1:
+ // vqadd<c><q>.s<size> {<Qd>,} <Qn>, <Qm>
+ //
+ // 111100100Dssnnn0ddd00000N1M1mmm0 where Dddd=OpQd, Nnnn=OpQn, Mmmm=OpQm,
+ // size is 8, 16, 32, or 64.
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vqaddqi expects vector with integer element type");
+ constexpr const char *Vqaddqi = "vqaddqi";
+ constexpr IValueT VqaddqiOpcode = B4;
+ emitSIMDqqq(VqaddqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vqaddqi);
+}
+
+void AssemblerARM32::vqaddqu(Type ElmtTy, const Operand *OpQd,
+ const Operand *OpQm, const Operand *OpQn) {
+ // VQADD (integer) - ARM section A8.6.369, encoding A1:
+ // vqadd<c><q>.s<size> {<Qd>,} <Qn>, <Qm>
+ //
+ // 111100110Dssnnn0ddd00000N1M1mmm0 where Dddd=OpQd, Nnnn=OpQn, Mmmm=OpQm,
+ // size is 8, 16, 32, or 64.
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vqaddqu expects vector with integer element type");
+ constexpr const char *Vqaddqu = "vqaddqu";
+ constexpr IValueT VqaddquOpcode = B24 | B4;
+ emitSIMDqqq(VqaddquOpcode, ElmtTy, OpQd, OpQm, OpQn, Vqaddqu);
+}
+
+void AssemblerARM32::vqsubqi(Type ElmtTy, const Operand *OpQd,
+ const Operand *OpQm, const Operand *OpQn) {
+ // VQSUB (integer) - ARM section A8.6.369, encoding A1:
+ // vqsub<c><q>.s<size> {<Qd>,} <Qn>, <Qm>
+ //
+ // 111100100Dssnnn0ddd00010N1M1mmm0 where Dddd=OpQd, Nnnn=OpQn, Mmmm=OpQm,
+ // size is 8, 16, 32, or 64.
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vqsubqi expects vector with integer element type");
+ constexpr const char *Vqsubqi = "vqsubqi";
+ constexpr IValueT VqsubqiOpcode = B9 | B4;
+ emitSIMDqqq(VqsubqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vqsubqi);
+}
+
+void AssemblerARM32::vqsubqu(Type ElmtTy, const Operand *OpQd,
+ const Operand *OpQm, const Operand *OpQn) {
+ // VQSUB (integer) - ARM section A8.6.369, encoding A1:
+ // vqsub<c><q>.s<size> {<Qd>,} <Qn>, <Qm>
+ //
+ // 111100110Dssnnn0ddd00010N1M1mmm0 where Dddd=OpQd, Nnnn=OpQn, Mmmm=OpQm,
+ // size is 8, 16, 32, or 64.
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vqsubqu expects vector with integer element type");
+ constexpr const char *Vqsubqu = "vqsubqu";
+ constexpr IValueT VqsubquOpcode = B24 | B9 | B4;
+ emitSIMDqqq(VqsubquOpcode, ElmtTy, OpQd, OpQm, OpQn, Vqsubqu);
+}
+
void AssemblerARM32::vsubqi(Type ElmtTy, const Operand *OpQd,
const Operand *OpQm, const Operand *OpQn) {
// VSUB (integer) - ARM section A8.8.414, encoding A1:
@@ -3395,6 +3894,59 @@
emitSIMDqqq(VsubqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vsubqi);
}
+void AssemblerARM32::vqmovn2(Type DestElmtTy, const Operand *OpQd,
+ const Operand *OpQm, const Operand *OpQn,
+ bool Unsigned, bool Saturating) {
+ // Pseudo-instruction for packing two quadword vectors into one quadword
+ // vector, narrowing each element using saturation or truncation.
+
+ // VQMOVN - ARMv7-A/R section A8.6.361, encoding A1:
+ // V{Q}MOVN{U}N<c>.<type><size> <Dd>, <Qm>
+ //
+ // 111100111D11ss10dddd0010opM0mmm0 where Ddddd=OpQd, op = 10, Mmmm=OpQm,
+ // ss is 00 (16-bit), 01 (32-bit), or 10 (64-bit).
+
+ assert(DestElmtTy != IceType_i64 &&
+ "vmovn doesn't allow i64 destination vector elements!");
+
+ constexpr const char *Vqmovn = "vqmovn";
+ constexpr bool UseQRegs = false;
+ constexpr bool IsFloatTy = false;
+ const IValueT Qd = encodeQRegister(OpQd, "Qd", Vqmovn);
+ const IValueT Qm = encodeQRegister(OpQm, "Qm", Vqmovn);
+ const IValueT Qn = encodeQRegister(OpQn, "Qn", Vqmovn);
+ const IValueT Dd = mapQRegToDReg(Qd);
+ const IValueT Dm = mapQRegToDReg(Qm);
+ const IValueT Dn = mapQRegToDReg(Qn);
+
+ IValueT VqmovnOpcode = B25 | B24 | B23 | B21 | B20 | B17 | B9 |
+ (Saturating ? (Unsigned ? B6 : B7) : 0);
+
+ constexpr IValueT ElmtShift = 18;
+ VqmovnOpcode |= (encodeElmtType(DestElmtTy) << ElmtShift);
+
+ if (Qm != Qd) {
+ // Narrow second source operand to upper half of destination.
+ emitSIMDBase(VqmovnOpcode, Dd + 1, 0, Dn, UseQRegs, IsFloatTy);
+ // Narrow first source operand to lower half of destination.
+ emitSIMDBase(VqmovnOpcode, Dd + 0, 0, Dm, UseQRegs, IsFloatTy);
+ } else if (Qn != Qd) {
+ // Narrow first source operand to lower half of destination.
+ emitSIMDBase(VqmovnOpcode, Dd + 0, 0, Dm, UseQRegs, IsFloatTy);
+ // Narrow second source operand to upper half of destination.
+ emitSIMDBase(VqmovnOpcode, Dd + 1, 0, Dn, UseQRegs, IsFloatTy);
+ } else {
+ // Narrow first source operand to lower half of destination.
+ emitSIMDBase(VqmovnOpcode, Dd, 0, Dm, UseQRegs, IsFloatTy);
+
+ // VMOV Dd, Dm
+ // 111100100D10mmmmdddd0001MQM1mmmm
+ const IValueT VmovOpcode = B25 | B21 | B8 | B4;
+
+ emitSIMDBase(VmovOpcode, Dd + 1, Dd, Dd, UseQRegs, IsFloatTy);
+ }
+}
+
void AssemblerARM32::vsubqf(const Operand *OpQd, const Operand *OpQn,
const Operand *OpQm) {
// VSUB (floating-point) - ARM section A8.8.415, Encoding A1:
@@ -3467,22 +4019,6 @@
emitSIMDqqq(VshlOpcode, ElmtTy, OpQd, OpQn, OpQm, Vshl);
}
-namespace {
-enum SIMDShiftType { ST_Vshl, ST_Vshr };
-IValueT encodeSIMDShiftImm6(SIMDShiftType Shift, Type ElmtTy,
- const ConstantInteger32 *Imm6) {
- const IValueT Imm = Imm6->getValue();
- assert(Imm > 0);
- const SizeT MaxShift = getScalarIntBitWidth(ElmtTy);
- assert(Imm < MaxShift);
- assert(ElmtTy == IceType_i8 || ElmtTy == IceType_i16 ||
- ElmtTy == IceType_i32);
- const IValueT VshlImm = Imm - MaxShift;
- const IValueT VshrImm = 2 * MaxShift - Imm;
- return ((Shift == ST_Vshl) ? VshlImm : VshrImm) & (2 * MaxShift - 1);
-}
-} // end of anonymous namespace
-
void AssemblerARM32::vshlqc(Type ElmtTy, const Operand *OpQd,
const Operand *OpQm,
const ConstantInteger32 *Imm6) {
@@ -3499,34 +4035,19 @@
encodeSIMDShiftImm6(ST_Vshl, ElmtTy, Imm6), Vshl);
}
-void AssemblerARM32::vshrqic(Type ElmtTy, const Operand *OpQd,
- const Operand *OpQm,
- const ConstantInteger32 *Imm6) {
+void AssemblerARM32::vshrqc(Type ElmtTy, const Operand *OpQd,
+ const Operand *OpQm, const ConstantInteger32 *Imm6,
+ InstARM32::FPSign Sign) {
// VSHR - ARM section A8.8.398, encoding A1:
// vshr Qd, Qm, #Imm
//
// 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
- // 0=U, 1=Q, 0=L.
+ // U=Unsigned, Q=1, L=0.
assert(isScalarIntegerType(ElmtTy) &&
"vshr expects vector with integer element type");
constexpr const char *Vshr = "vshr";
- constexpr IValueT VshrOpcode = B23 | B4;
- emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
- encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
-}
-
-void AssemblerARM32::vshrquc(Type ElmtTy, const Operand *OpQd,
- const Operand *OpQm,
- const ConstantInteger32 *Imm6) {
- // VSHR - ARM section A8.8.398, encoding A1:
- // vshr Qd, Qm, #Imm
- //
- // 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
- // 0=U, 1=Q, 0=L.
- assert(isScalarIntegerType(ElmtTy) &&
- "vshr expects vector with integer element type");
- constexpr const char *Vshr = "vshr";
- constexpr IValueT VshrOpcode = B23 | B4;
+ const IValueT VshrOpcode =
+ (Sign == InstARM32::FS_Unsigned ? B24 : 0) | B23 | B4;
emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
}
diff --git a/third_party/subzero/src/IceAssemblerARM32.h b/third_party/subzero/src/IceAssemblerARM32.h
index 84ca973..43c3f56 100644
--- a/third_party/subzero/src/IceAssemblerARM32.h
+++ b/third_party/subzero/src/IceAssemblerARM32.h
@@ -440,16 +440,34 @@
vldrs(OpSd, OpAddress, Cond, TInfo);
}
+ void vldrq(const Operand *OpQd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetInfo &TInfo);
+
+ void vldrq(const Operand *OpQd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetLowering *Lowering) {
+ const TargetInfo TInfo(Lowering);
+ vldrq(OpQd, OpAddress, Cond, TInfo);
+ }
+
// ElmtSize = #bits in vector element.
void vld1qr(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
const TargetInfo &TInfo);
+ void vld1(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
+ const TargetInfo &TInfo);
+
void vld1qr(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
const TargetLowering *Lowering) {
const TargetInfo TInfo(Lowering);
vld1qr(ElmtSize, OpQd, OpRn, TInfo);
}
+ void vld1(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
+ const TargetLowering *Lowering) {
+ const TargetInfo TInfo(Lowering);
+ vld1(ElmtSize, OpQd, OpRn, TInfo);
+ }
+
// Qn[i] = Imm for all i in vector. Returns true iff Imm can be defined as an
// Imm8 using AdvSIMDExpandImm().
bool vmovqc(const Operand *OpQd, const ConstantInteger32 *Imm);
@@ -520,6 +538,21 @@
void vmulqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
const Operand *OpQm);
+ // Integer vector multiply high.
+ void vmulh(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm, bool Unsigned);
+
+ // Integer vector multiply add pairwise.
+ void vmlap(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm);
+
+ // Vector element replication.
+ void vdup(Type ElmtTy, const Operand *OpQd, const Operand *OpQn, IValueT Idx);
+
+ // Vector interleave lower halves.
+ void vzip(Type ElmtTy, const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm);
+
// Float vector multiply.
void vmulqf(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
@@ -528,6 +561,11 @@
void vmvnq(const Operand *OpQd, const Operand *OpQm);
+ void vmovlq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
+ void vmovhq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
+ void vmovhlq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
+ void vmovlhq(const Operand *OpQd, const Operand *OpQn, const Operand *OpQm);
+
void vnegqs(const Operand *OpQd, const Operand *OpQm);
void vnegqs(Type ElmtTy, const Operand *OpQd, const Operand *OpQm);
@@ -549,11 +587,8 @@
void vshlqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const ConstantInteger32 *OpQn);
- void vshrqic(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
- const ConstantInteger32 *OpQn);
-
- void vshrquc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
- const ConstantInteger32 *OpQn);
+ void vshrqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
+ const ConstantInteger32 *OpQn, InstARM32::FPSign Sign);
void vsqrtd(const Operand *OpDd, const Operand *OpDm, CondARM32::Cond Cond);
@@ -577,6 +612,15 @@
vstrs(OpSd, OpAddress, Cond, TInfo);
}
+ void vstrq(const Operand *OpQd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetInfo &TInfo);
+
+ void vstrq(const Operand *OpQd, const Operand *OpAddress,
+ CondARM32::Cond Cond, const TargetLowering *Lowering) {
+ const TargetInfo TInfo(Lowering);
+ vstrq(OpQd, OpAddress, Cond, TInfo);
+ }
+
// ElmtSize = #bits in vector element.
void vst1qr(size_t ElmtSize, const Operand *OpQd, const Operand *OpAddress,
const TargetInfo &TInfo);
@@ -587,6 +631,15 @@
vst1qr(ElmtSize, OpQd, OpRn, TInfo);
}
+ void vst1(size_t ElmtSize, const Operand *OpQd, const Operand *OpAddress,
+ const TargetInfo &TInfo);
+
+ void vst1(size_t ElmtSize, const Operand *OpQd, const Operand *OpRn,
+ const TargetLowering *Lowering) {
+ const TargetInfo TInfo(Lowering);
+ vst1(ElmtSize, OpQd, OpRn, TInfo);
+ }
+
void vsubd(const Operand *OpDd, const Operand *OpDn, const Operand *OpDm,
CondARM32::Cond Cond);
@@ -594,6 +647,22 @@
void vsubqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const Operand *OpQn);
+ // Integer vector saturating subtract.
+ void vqsubqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
+ const Operand *OpQn);
+ void vqsubqu(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
+ const Operand *OpQn);
+
+ // Integer vector saturating add.
+ void vqaddqi(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
+ const Operand *OpQn);
+ void vqaddqu(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
+ const Operand *OpQn);
+
+ // Integer vector packing with optional saturation.
+ void vqmovn2(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
+ const Operand *OpQn, bool Unsigned, bool Saturating);
+
// Float vector subtract
void vsubqf(const Operand *OpQd, const Operand *OpQm, const Operand *OpQn);
@@ -723,6 +792,11 @@
DRegListSize NumDRegs, size_t ElmtSize, IValueT Align,
const char *InstName);
+ // Pattern 111100000D00nnnnddddss00aaaammmm | Opcode where Ddddd=Dd, nnnn=Rn,
+ // mmmmm=Rm, ElmtSize in {8, 16, 32) and defines ss, and aa=Align.
+ void emitVMem1Op(IValueT Opcode, IValueT Dd, IValueT Rn, IValueT Rm,
+ size_t ElmtSize, IValueT Align, const char *InstName);
+
// Pattern cccc011100x1dddd1111mmmm0001nnn where cccc=Cond,
// x=Opcode, dddd=Rd, nnnn=Rn, mmmm=Rm.
void emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, IValueT Rn,
diff --git a/third_party/subzero/src/IceGlobalContext.cpp b/third_party/subzero/src/IceGlobalContext.cpp
index 45fb999..3a21b3a 100644
--- a/third_party/subzero/src/IceGlobalContext.cpp
+++ b/third_party/subzero/src/IceGlobalContext.cpp
@@ -372,6 +372,11 @@
}
}
+void GlobalContext::translateFunctionsWrapper(ThreadContext *MyTLS) {
+ ICE_TLS_SET_FIELD(TLS, MyTLS);
+ translateFunctions();
+}
+
void GlobalContext::translateFunctions() {
TimerMarker Timer(TimerStack::TT_translateFunctions, this);
while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) {
@@ -454,6 +459,9 @@
} // end of anonymous namespace
+// static
+void GlobalContext::TlsInit() { ICE_TLS_INIT_FIELD(TLS); }
+
void GlobalContext::emitFileHeader() {
TimerMarker T1(Ice::TimerStack::TT_emitAsm, this);
if (getFlags().getOutFileType() == FT_Elf) {
@@ -556,6 +564,11 @@
lowerGlobals(ProfileDataSection);
}
+void GlobalContext::emitterWrapper(ThreadContext *MyTLS) {
+ ICE_TLS_SET_FIELD(TLS, MyTLS);
+ emitItems();
+}
+
void GlobalContext::emitItems() {
const bool Threaded = !getFlags().isSequential();
// Pending is a vector containing the reassembled, ordered list of
@@ -987,6 +1000,38 @@
return EmitQ.blockingPop();
}
+void GlobalContext::initParserThread() {
+ ThreadContext *Tls = new ThreadContext();
+ auto Timers = getTimers();
+ Timers->initInto(Tls->Timers);
+ AllThreadContexts.push_back(Tls);
+ ICE_TLS_SET_FIELD(TLS, Tls);
+}
+
+void GlobalContext::startWorkerThreads() {
+ size_t NumWorkers = getFlags().getNumTranslationThreads();
+ auto Timers = getTimers();
+ for (size_t i = 0; i < NumWorkers; ++i) {
+ ThreadContext *WorkerTLS = new ThreadContext();
+ Timers->initInto(WorkerTLS->Timers);
+ AllThreadContexts.push_back(WorkerTLS);
+ TranslationThreads.push_back(std::thread(
+ &GlobalContext::translateFunctionsWrapper, this, WorkerTLS));
+ }
+ if (NumWorkers) {
+ ThreadContext *WorkerTLS = new ThreadContext();
+ Timers->initInto(WorkerTLS->Timers);
+ AllThreadContexts.push_back(WorkerTLS);
+ EmitterThreads.push_back(
+ std::thread(&GlobalContext::emitterWrapper, this, WorkerTLS));
+ }
+}
+
+void GlobalContext::resetStats() {
+ if (BuildDefs::dump())
+ ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset();
+}
+
void GlobalContext::dumpStats(const Cfg *Func) {
if (!getFlags().getDumpStats())
return;
@@ -997,6 +1042,54 @@
}
}
+void GlobalContext::statsUpdateEmitted(uint32_t InstCount) {
+ if (!getFlags().getDumpStats())
+ return;
+ ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
+ Tls->StatsFunction.update(CodeStats::CS_InstCount, InstCount);
+ Tls->StatsCumulative.update(CodeStats::CS_InstCount, InstCount);
+}
+
+void GlobalContext::statsUpdateRegistersSaved(uint32_t Num) {
+ if (!getFlags().getDumpStats())
+ return;
+ ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
+ Tls->StatsFunction.update(CodeStats::CS_RegsSaved, Num);
+ Tls->StatsCumulative.update(CodeStats::CS_RegsSaved, Num);
+}
+
+void GlobalContext::statsUpdateFrameBytes(uint32_t Bytes) {
+ if (!getFlags().getDumpStats())
+ return;
+ ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
+ Tls->StatsFunction.update(CodeStats::CS_FrameByte, Bytes);
+ Tls->StatsCumulative.update(CodeStats::CS_FrameByte, Bytes);
+}
+
+void GlobalContext::statsUpdateSpills() {
+ if (!getFlags().getDumpStats())
+ return;
+ ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
+ Tls->StatsFunction.update(CodeStats::CS_NumSpills);
+ Tls->StatsCumulative.update(CodeStats::CS_NumSpills);
+}
+
+void GlobalContext::statsUpdateFills() {
+ if (!getFlags().getDumpStats())
+ return;
+ ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
+ Tls->StatsFunction.update(CodeStats::CS_NumFills);
+ Tls->StatsCumulative.update(CodeStats::CS_NumFills);
+}
+
+void GlobalContext::statsUpdateRPImms() {
+ if (!getFlags().getDumpStats())
+ return;
+ ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
+ Tls->StatsFunction.update(CodeStats::CS_NumRPImms);
+ Tls->StatsCumulative.update(CodeStats::CS_NumRPImms);
+}
+
void GlobalContext::dumpTimers(TimerStackIdT StackID, bool DumpCumulative) {
if (!BuildDefs::timers())
return;
diff --git a/third_party/subzero/src/IceGlobalContext.h b/third_party/subzero/src/IceGlobalContext.h
index aed4341..55b37d8 100644
--- a/third_party/subzero/src/IceGlobalContext.h
+++ b/third_party/subzero/src/IceGlobalContext.h
@@ -297,55 +297,16 @@
ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); }
/// Reset stats at the beginning of a function.
- void resetStats() {
- if (BuildDefs::dump())
- ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset();
- }
+ void resetStats();
void dumpStats(const Cfg *Func = nullptr);
- void statsUpdateEmitted(uint32_t InstCount) {
- if (!getFlags().getDumpStats())
- return;
- ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
- Tls->StatsFunction.update(CodeStats::CS_InstCount, InstCount);
- Tls->StatsCumulative.update(CodeStats::CS_InstCount, InstCount);
- }
- void statsUpdateRegistersSaved(uint32_t Num) {
- if (!getFlags().getDumpStats())
- return;
- ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
- Tls->StatsFunction.update(CodeStats::CS_RegsSaved, Num);
- Tls->StatsCumulative.update(CodeStats::CS_RegsSaved, Num);
- }
- void statsUpdateFrameBytes(uint32_t Bytes) {
- if (!getFlags().getDumpStats())
- return;
- ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
- Tls->StatsFunction.update(CodeStats::CS_FrameByte, Bytes);
- Tls->StatsCumulative.update(CodeStats::CS_FrameByte, Bytes);
- }
- void statsUpdateSpills() {
- if (!getFlags().getDumpStats())
- return;
- ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
- Tls->StatsFunction.update(CodeStats::CS_NumSpills);
- Tls->StatsCumulative.update(CodeStats::CS_NumSpills);
- }
- void statsUpdateFills() {
- if (!getFlags().getDumpStats())
- return;
- ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
- Tls->StatsFunction.update(CodeStats::CS_NumFills);
- Tls->StatsCumulative.update(CodeStats::CS_NumFills);
- }
+ void statsUpdateEmitted(uint32_t InstCount);
+ void statsUpdateRegistersSaved(uint32_t Num);
+ void statsUpdateFrameBytes(uint32_t Bytes);
+ void statsUpdateSpills();
+ void statsUpdateFills();
/// Number of Randomized or Pooled Immediates
- void statsUpdateRPImms() {
- if (!getFlags().getDumpStats())
- return;
- ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
- Tls->StatsFunction.update(CodeStats::CS_NumRPImms);
- Tls->StatsCumulative.update(CodeStats::CS_NumRPImms);
- }
+ void statsUpdateRPImms();
/// These are predefined TimerStackIdT values.
enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num };
@@ -403,32 +364,8 @@
std::unique_ptr<EmitterWorkItem> emitQueueBlockingPop();
void emitQueueNotifyEnd() { EmitQ.notifyEnd(); }
- void initParserThread() {
- ThreadContext *Tls = new ThreadContext();
- auto Timers = getTimers();
- Timers->initInto(Tls->Timers);
- AllThreadContexts.push_back(Tls);
- ICE_TLS_SET_FIELD(TLS, Tls);
- }
-
- void startWorkerThreads() {
- size_t NumWorkers = getFlags().getNumTranslationThreads();
- auto Timers = getTimers();
- for (size_t i = 0; i < NumWorkers; ++i) {
- ThreadContext *WorkerTLS = new ThreadContext();
- Timers->initInto(WorkerTLS->Timers);
- AllThreadContexts.push_back(WorkerTLS);
- TranslationThreads.push_back(std::thread(
- &GlobalContext::translateFunctionsWrapper, this, WorkerTLS));
- }
- if (NumWorkers) {
- ThreadContext *WorkerTLS = new ThreadContext();
- Timers->initInto(WorkerTLS->Timers);
- AllThreadContexts.push_back(WorkerTLS);
- EmitterThreads.push_back(
- std::thread(&GlobalContext::emitterWrapper, this, WorkerTLS));
- }
- }
+ void initParserThread();
+ void startWorkerThreads();
void waitForWorkerThreads();
@@ -444,18 +381,12 @@
}
/// Translation thread startup routine.
- void translateFunctionsWrapper(ThreadContext *MyTLS) {
- ICE_TLS_SET_FIELD(TLS, MyTLS);
- translateFunctions();
- }
+ void translateFunctionsWrapper(ThreadContext *MyTLS);
/// Translate functions from the Cfg queue until the queue is empty.
void translateFunctions();
/// Emitter thread startup routine.
- void emitterWrapper(ThreadContext *MyTLS) {
- ICE_TLS_SET_FIELD(TLS, MyTLS);
- emitItems();
- }
+ void emitterWrapper(ThreadContext *MyTLS);
/// Emit functions and global initializers from the emitter queue until the
/// queue is empty.
void emitItems();
@@ -643,7 +574,7 @@
ICE_TLS_DECLARE_FIELD(ThreadContext *, TLS);
public:
- static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); }
+ static void TlsInit();
};
/// Helper class to push and pop a timer marker. The constructor pushes a
diff --git a/third_party/subzero/src/IceInst.h b/third_party/subzero/src/IceInst.h
index 889ead5..187c16d 100644
--- a/third_party/subzero/src/IceInst.h
+++ b/third_party/subzero/src/IceInst.h
@@ -997,35 +997,45 @@
return Indexes[Pos];
}
- inline bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3,
- int32_t i4, int32_t i5, int32_t i6, int32_t i7) const {
+ int32_t getIndexValue(SizeT Pos) const { return getIndex(Pos)->getValue(); }
+
+ bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3) const {
+ static constexpr SizeT ExpectedNumElements = 4;
+ assert(ExpectedNumElements == getNumIndexes());
+ (void)ExpectedNumElements;
+
+ return getIndexValue(0) == i0 && getIndexValue(1) == i1 &&
+ getIndexValue(2) == i2 && getIndexValue(3) == i3;
+ }
+
+ bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3, int32_t i4,
+ int32_t i5, int32_t i6, int32_t i7) const {
static constexpr SizeT ExpectedNumElements = 8;
assert(ExpectedNumElements == getNumIndexes());
(void)ExpectedNumElements;
- return getIndex(0)->getValue() == i0 && getIndex(1)->getValue() == i1 &&
- getIndex(2)->getValue() == i2 && getIndex(3)->getValue() == i3 &&
- getIndex(4)->getValue() == i4 && getIndex(5)->getValue() == i5 &&
- getIndex(6)->getValue() == i6 && getIndex(7)->getValue() == i7;
+ return getIndexValue(0) == i0 && getIndexValue(1) == i1 &&
+ getIndexValue(2) == i2 && getIndexValue(3) == i3 &&
+ getIndexValue(4) == i4 && getIndexValue(5) == i5 &&
+ getIndexValue(6) == i6 && getIndexValue(7) == i7;
}
- inline bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3,
- int32_t i4, int32_t i5, int32_t i6, int32_t i7,
- int32_t i8, int32_t i9, int32_t i10, int32_t i11,
- int32_t i12, int32_t i13, int32_t i14,
- int32_t i15) const {
+ bool indexesAre(int32_t i0, int32_t i1, int32_t i2, int32_t i3, int32_t i4,
+ int32_t i5, int32_t i6, int32_t i7, int32_t i8, int32_t i9,
+ int32_t i10, int32_t i11, int32_t i12, int32_t i13,
+ int32_t i14, int32_t i15) const {
static constexpr SizeT ExpectedNumElements = 16;
assert(ExpectedNumElements == getNumIndexes());
(void)ExpectedNumElements;
- return getIndex(0)->getValue() == i0 && getIndex(1)->getValue() == i1 &&
- getIndex(2)->getValue() == i2 && getIndex(3)->getValue() == i3 &&
- getIndex(4)->getValue() == i4 && getIndex(5)->getValue() == i5 &&
- getIndex(6)->getValue() == i6 && getIndex(7)->getValue() == i7 &&
- getIndex(8)->getValue() == i8 && getIndex(9)->getValue() == i9 &&
- getIndex(10)->getValue() == i10 && getIndex(11)->getValue() == i11 &&
- getIndex(12)->getValue() == i12 && getIndex(13)->getValue() == i13 &&
- getIndex(14)->getValue() == i14 && getIndex(15)->getValue() == i15;
+ return getIndexValue(0) == i0 && getIndexValue(1) == i1 &&
+ getIndexValue(2) == i2 && getIndexValue(3) == i3 &&
+ getIndexValue(4) == i4 && getIndexValue(5) == i5 &&
+ getIndexValue(6) == i6 && getIndexValue(7) == i7 &&
+ getIndexValue(8) == i8 && getIndexValue(9) == i9 &&
+ getIndexValue(10) == i10 && getIndexValue(11) == i11 &&
+ getIndexValue(12) == i12 && getIndexValue(13) == i13 &&
+ getIndexValue(14) == i14 && getIndexValue(15) == i15;
}
bool isMemoryWrite() const override { return false; }
diff --git a/third_party/subzero/src/IceInstARM32.cpp b/third_party/subzero/src/IceInstARM32.cpp
index 4bd530c..646730f 100644
--- a/third_party/subzero/src/IceInstARM32.cpp
+++ b/third_party/subzero/src/IceInstARM32.cpp
@@ -903,6 +903,82 @@
}
}
+template <> void InstARM32Vmovl::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Variable *Dest = getDest();
+ switch (Dest->getType()) {
+ default:
+ llvm::report_fatal_error("Vmovlq not defined on type " +
+ typeStdString(Dest->getType()));
+ case IceType_v4i1:
+ case IceType_v8i1:
+ case IceType_v16i1:
+ case IceType_v16i8:
+ case IceType_v8i16:
+ case IceType_v4i32:
+ case IceType_v4f32: {
+ Asm->vmovlq(Dest, getSrc(0), getSrc(1));
+ } break;
+ }
+}
+
+template <> void InstARM32Vmovh::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Variable *Dest = getDest();
+ switch (Dest->getType()) {
+ default:
+ llvm::report_fatal_error("Vmovhq not defined on type " +
+ typeStdString(Dest->getType()));
+ case IceType_v4i1:
+ case IceType_v8i1:
+ case IceType_v16i1:
+ case IceType_v16i8:
+ case IceType_v8i16:
+ case IceType_v4i32:
+ case IceType_v4f32: {
+ Asm->vmovhq(Dest, getSrc(0), getSrc(1));
+ } break;
+ }
+}
+
+template <> void InstARM32Vmovhl::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Variable *Dest = getDest();
+ switch (Dest->getType()) {
+ default:
+ llvm::report_fatal_error("Vmovhlq not defined on type " +
+ typeStdString(Dest->getType()));
+ case IceType_v4i1:
+ case IceType_v8i1:
+ case IceType_v16i1:
+ case IceType_v16i8:
+ case IceType_v8i16:
+ case IceType_v4i32:
+ case IceType_v4f32: {
+ Asm->vmovhlq(Dest, getSrc(0), getSrc(1));
+ } break;
+ }
+}
+
+template <> void InstARM32Vmovlh::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Variable *Dest = getDest();
+ switch (Dest->getType()) {
+ default:
+ llvm::report_fatal_error("Vmovlhq not defined on type " +
+ typeStdString(Dest->getType()));
+ case IceType_v4i1:
+ case IceType_v8i1:
+ case IceType_v16i1:
+ case IceType_v16i8:
+ case IceType_v8i16:
+ case IceType_v4i32:
+ case IceType_v4f32: {
+ Asm->vmovlhq(Dest, getSrc(0), getSrc(1));
+ } break;
+ }
+}
+
template <> void InstARM32Vneg::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
const Variable *Dest = getDest();
@@ -999,15 +1075,13 @@
case IceType_v4i32: {
const Type ElmtTy = typeElementType(DestTy);
const auto *Imm6 = llvm::cast<ConstantInteger32>(getSrc(1));
- assert(Sign != InstARM32::FS_None);
switch (Sign) {
- case InstARM32::FS_None: // defaults to unsigned.
- case InstARM32::FS_Unsigned:
- Asm->vshrquc(ElmtTy, Dest, getSrc(0), Imm6);
- break;
case InstARM32::FS_Signed:
- Asm->vshrqic(ElmtTy, Dest, getSrc(0), Imm6);
+ case InstARM32::FS_Unsigned:
+ Asm->vshrqc(ElmtTy, Dest, getSrc(0), Imm6, Sign);
break;
+ default:
+ assert(false && "Vshr requires signedness specification.");
}
} break;
}
@@ -1039,6 +1113,146 @@
assert(!Asm->needsTextFixup());
}
+template <> void InstARM32Vqadd::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Variable *Dest = getDest();
+ Type DestTy = Dest->getType();
+ switch (DestTy) {
+ default:
+ llvm::report_fatal_error("Vqadd not defined on type " +
+ typeStdString(DestTy));
+ case IceType_v16i8:
+ case IceType_v8i16:
+ case IceType_v4i32:
+ switch (Sign) {
+ case InstARM32::FS_None: // defaults to unsigned.
+ case InstARM32::FS_Unsigned:
+ Asm->vqaddqu(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
+ break;
+ case InstARM32::FS_Signed:
+ Asm->vqaddqi(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
+ break;
+ }
+ break;
+ }
+ assert(!Asm->needsTextFixup());
+}
+
+template <> void InstARM32Vqsub::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Variable *Dest = getDest();
+ Type DestTy = Dest->getType();
+ switch (DestTy) {
+ default:
+ llvm::report_fatal_error("Vqsub not defined on type " +
+ typeStdString(DestTy));
+ case IceType_v16i8:
+ case IceType_v8i16:
+ case IceType_v4i32:
+ switch (Sign) {
+ case InstARM32::FS_None: // defaults to unsigned.
+ case InstARM32::FS_Unsigned:
+ Asm->vqsubqu(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
+ break;
+ case InstARM32::FS_Signed:
+ Asm->vqsubqi(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
+ break;
+ }
+ break;
+ }
+ assert(!Asm->needsTextFixup());
+}
+
+template <> void InstARM32Vqmovn2::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Operand *Src0 = getSrc(0);
+ const Operand *Src1 = getSrc(1);
+ Type SrcTy = Src0->getType();
+ Type DestTy = Dest->getType();
+ bool Unsigned = true;
+ bool Saturating = true;
+ switch (SrcTy) {
+ default:
+ llvm::report_fatal_error("Vqmovn2 not defined on type " +
+ typeStdString(SrcTy));
+ case IceType_v8i16:
+ case IceType_v4i32:
+ switch (Sign) {
+ case InstARM32::FS_None:
+ Unsigned = true;
+ Saturating = false;
+ Asm->vqmovn2(typeElementType(DestTy), Dest, Src0, Src1, Unsigned,
+ Saturating);
+ break;
+ case InstARM32::FS_Unsigned:
+ Unsigned = true;
+ Saturating = true;
+ Asm->vqmovn2(typeElementType(DestTy), Dest, Src0, Src1, Unsigned,
+ Saturating);
+ break;
+ case InstARM32::FS_Signed:
+ Unsigned = false;
+ Saturating = true;
+ Asm->vqmovn2(typeElementType(DestTy), Dest, Src0, Src1, Unsigned,
+ Saturating);
+ break;
+ }
+ break;
+ }
+ assert(!Asm->needsTextFixup());
+}
+
+template <> void InstARM32Vmulh::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Operand *Src0 = getSrc(0);
+ Type SrcTy = Src0->getType();
+ bool Unsigned = true;
+ switch (SrcTy) {
+ default:
+ llvm::report_fatal_error("Vmulh not defined on type " +
+ typeStdString(SrcTy));
+ case IceType_v8i16:
+ switch (Sign) {
+ case InstARM32::FS_None: // defaults to unsigned.
+ case InstARM32::FS_Unsigned:
+ Unsigned = true;
+ Asm->vmulh(typeElementType(SrcTy), Dest, getSrc(0), getSrc(1), Unsigned);
+ break;
+ case InstARM32::FS_Signed:
+ Unsigned = false;
+ Asm->vmulh(typeElementType(SrcTy), Dest, getSrc(0), getSrc(1), Unsigned);
+ break;
+ }
+ break;
+ }
+ assert(!Asm->needsTextFixup());
+}
+
+template <> void InstARM32Vmlap::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Operand *Src0 = getSrc(0);
+ const Operand *Src1 = getSrc(1);
+ Type SrcTy = Src0->getType();
+ switch (SrcTy) {
+ default:
+ llvm::report_fatal_error("Vmlap not defined on type " +
+ typeStdString(SrcTy));
+ case IceType_v8i16:
+ Asm->vmlap(typeElementType(SrcTy), Dest, Src0, Src1);
+ break;
+ }
+ assert(!Asm->needsTextFixup());
+}
+
+template <> void InstARM32Vzip::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Operand *Src0 = getSrc(0);
+ const Operand *Src1 = getSrc(1);
+ Type DestTy = Dest->getType();
+ Asm->vzip(typeElementType(DestTy), Dest, Src0, Src1);
+ assert(!Asm->needsTextFixup());
+}
+
template <> void InstARM32Vmul::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
const Variable *Dest = getDest();
@@ -1288,6 +1502,20 @@
addSource(Mem);
}
+InstARM32Vstr1::InstARM32Vstr1(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
+ CondARM32::Cond Predicate, SizeT Size)
+ : InstARM32Pred(Func, InstARM32::Vstr1, 2, nullptr, Predicate) {
+ addSource(Value);
+ addSource(Mem);
+ this->Size = Size;
+}
+
+InstARM32Vdup::InstARM32Vdup(Cfg *Func, Variable *Dest, Variable *Src,
+ IValueT Idx)
+ : InstARM32Pred(Func, InstARM32::Vdup, 1, Dest, CondARM32::AL), Idx(Idx) {
+ addSource(Src);
+}
+
InstARM32Trap::InstARM32Trap(Cfg *Func)
: InstARM32(Func, InstARM32::Trap, 0, nullptr) {}
@@ -1606,6 +1834,8 @@
// Mov-like ops
template <> const char *InstARM32Ldr::Opcode = "ldr";
template <> const char *InstARM32Ldrex::Opcode = "ldrex";
+template <> const char *InstARM32Vldr1d::Opcode = "vldr1d";
+template <> const char *InstARM32Vldr1q::Opcode = "vldr1q";
// Three-addr ops
template <> const char *InstARM32Adc::Opcode = "adc";
template <> const char *InstARM32Add::Opcode = "add";
@@ -1636,11 +1866,26 @@
template <> const char *InstARM32Vmls::Opcode = "vmls";
template <> const char *InstARM32Vmul::Opcode = "vmul";
template <> const char *InstARM32Vmvn::Opcode = "vmvn";
+template <> const char *InstARM32Vmovl::Opcode = "vmovl";
+template <> const char *InstARM32Vmovh::Opcode = "vmovh";
+template <> const char *InstARM32Vmovhl::Opcode = "vmovhl";
+template <> const char *InstARM32Vmovlh::Opcode = "vmovlh";
template <> const char *InstARM32Vorr::Opcode = "vorr";
template <> const char *InstARM32UnaryopFP<InstARM32::Vneg>::Opcode = "vneg";
template <> const char *InstARM32ThreeAddrFP<InstARM32::Vshl>::Opcode = "vshl";
template <> const char *InstARM32ThreeAddrFP<InstARM32::Vshr>::Opcode = "vshr";
template <> const char *InstARM32Vsub::Opcode = "vsub";
+template <>
+const char *InstARM32ThreeAddrFP<InstARM32::Vqadd>::Opcode = "vqadd";
+template <>
+const char *InstARM32ThreeAddrFP<InstARM32::Vqsub>::Opcode = "vqsub";
+template <>
+const char *InstARM32ThreeAddrFP<InstARM32::Vqmovn2>::Opcode = "vqmovn2";
+template <>
+const char *InstARM32ThreeAddrFP<InstARM32::Vmulh>::Opcode = "vmulh";
+template <>
+const char *InstARM32ThreeAddrFP<InstARM32::Vmlap>::Opcode = "vmlap";
+template <> const char *InstARM32ThreeAddrFP<InstARM32::Vzip>::Opcode = "vzip";
// Four-addr ops
template <> const char *InstARM32Mla::Opcode = "mla";
template <> const char *InstARM32Mls::Opcode = "mls";
@@ -2102,6 +2347,62 @@
getSrc(0)->emit(Func);
}
+template <> void InstARM32Vldr1d::emit(const Cfg *Func) const {
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 1);
+ assert(getDest()->hasReg());
+ Variable *Dest = getDest();
+ Type Ty = Dest->getType();
+ const bool IsVector = isVectorType(Ty);
+ const bool IsScalarFloat = isScalarFloatingType(Ty);
+ const char *ActualOpcode =
+ IsVector ? "vld1" : (IsScalarFloat ? "vldr" : "ldr");
+ const char *WidthString = IsVector ? "" : getWidthString(Ty);
+ Str << "\t" << ActualOpcode;
+ const bool IsVInst = IsVector || IsScalarFloat;
+ if (IsVInst) {
+ Str << getPredicate() << WidthString;
+ } else {
+ Str << WidthString << getPredicate();
+ }
+ if (IsVector)
+ Str << "." << getVecElmtBitsize(Ty);
+ Str << "\t";
+ getDest()->emit(Func);
+ Str << ", ";
+ getSrc(0)->emit(Func);
+}
+
+template <> void InstARM32Vldr1q::emit(const Cfg *Func) const {
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 1);
+ assert(getDest()->hasReg());
+ Variable *Dest = getDest();
+ Type Ty = Dest->getType();
+ const bool IsVector = isVectorType(Ty);
+ const bool IsScalarFloat = isScalarFloatingType(Ty);
+ const char *ActualOpcode =
+ IsVector ? "vld1" : (IsScalarFloat ? "vldr" : "ldr");
+ const char *WidthString = IsVector ? "" : getWidthString(Ty);
+ Str << "\t" << ActualOpcode;
+ const bool IsVInst = IsVector || IsScalarFloat;
+ if (IsVInst) {
+ Str << getPredicate() << WidthString;
+ } else {
+ Str << WidthString << getPredicate();
+ }
+ if (IsVector)
+ Str << "." << getVecElmtBitsize(Ty);
+ Str << "\t";
+ getDest()->emit(Func);
+ Str << ", ";
+ getSrc(0)->emit(Func);
+}
+
template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 1);
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
@@ -2135,6 +2436,20 @@
}
}
+template <> void InstARM32Vldr1d::emitIAS(const Cfg *Func) const {
+ assert(getSrcSize() == 1);
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ Variable *Dest = getDest();
+ Asm->vld1(32, Dest, getSrc(0), Func->getTarget());
+}
+
+template <> void InstARM32Vldr1q::emitIAS(const Cfg *Func) const {
+ assert(getSrcSize() == 1);
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ Variable *Dest = getDest();
+ Asm->vld1(64, Dest, getSrc(0), Func->getTarget());
+}
+
template <> void InstARM32Ldrex::emit(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
@@ -2541,6 +2856,88 @@
getSrc(0)->dump(Func);
}
+void InstARM32Vstr1::emit(const Cfg *Func) const {
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 2);
+ Type Ty = getSrc(0)->getType();
+ const bool IsVectorStore = isVectorType(Ty);
+ const bool IsScalarFloat = isScalarFloatingType(Ty);
+ const char *Opcode =
+ IsVectorStore ? "vst1" : (IsScalarFloat ? "vstr" : "str");
+ Str << "\t" << Opcode;
+ const bool IsVInst = IsVectorStore || IsScalarFloat;
+ if (IsVInst) {
+ Str << getPredicate() << getWidthString(Ty);
+ } else {
+ Str << getWidthString(Ty) << getPredicate();
+ }
+ if (IsVectorStore)
+ Str << "." << getVecElmtBitsize(Ty);
+ Str << "\t";
+ getSrc(0)->emit(Func);
+ Str << ", ";
+ getSrc(1)->emit(Func);
+}
+
+void InstARM32Vstr1::emitIAS(const Cfg *Func) const {
+ assert(getSrcSize() == 2);
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Operand *Src0 = getSrc(0);
+ const Operand *Src1 = getSrc(1);
+ Asm->vst1(Size, Src0, Src1, Func->getTarget());
+}
+
+void InstARM32Vstr1::dump(const Cfg *Func) const {
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrDump();
+ Type Ty = getSrc(0)->getType();
+ dumpOpcodePred(Str, "str", Ty);
+ Str << " ";
+ getSrc(1)->dump(Func);
+ Str << ", ";
+ getSrc(0)->dump(Func);
+}
+
+void InstARM32Vdup::emit(const Cfg *Func) const {
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrEmit();
+ assert(getSrcSize() == 2);
+ Type Ty = getSrc(0)->getType();
+ const char *Opcode = "vdup";
+ Str << "\t" << Opcode;
+ Str << getPredicate() << "." << getWidthString(Ty) << getVecElmtBitsize(Ty);
+ Str << "\t";
+ getSrc(0)->emit(Func);
+ Str << ", ";
+ getSrc(1)->emit(Func);
+ Str << ", " << Idx;
+}
+
+void InstARM32Vdup::emitIAS(const Cfg *Func) const {
+ assert(getSrcSize() == 1);
+ auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
+ const Operand *Dest = getDest();
+ const Operand *Src = getSrc(0);
+ Type DestTy = Dest->getType();
+ Asm->vdup(typeElementType(DestTy), Dest, Src, Idx);
+}
+
+void InstARM32Vdup::dump(const Cfg *Func) const {
+ if (!BuildDefs::dump())
+ return;
+ Ostream &Str = Func->getContext()->getStrDump();
+ dumpDest(Func);
+ Str << " = ";
+ dumpOpcodePred(Str, "vdup", getDest()->getType());
+ Str << " ";
+ dumpSources(Func);
+ Str << ", " << Idx;
+}
+
void InstARM32Trap::emit(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
@@ -3112,10 +3509,17 @@
template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vshl>;
template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vshr>;
template class InstARM32ThreeAddrFP<InstARM32::Vsub>;
+template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vqadd>;
+template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vqsub>;
+template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vqmovn2>;
+template class InstARM32ThreeAddrSignAwareFP<InstARM32::Vmulh>;
+template class InstARM32ThreeAddrFP<InstARM32::Vmlap>;
template class InstARM32LoadBase<InstARM32::Ldr>;
template class InstARM32LoadBase<InstARM32::Ldrex>;
-
+template class InstARM32LoadBase<InstARM32::Vldr1d>;
+template class InstARM32LoadBase<InstARM32::Vldr1q>;
+template class InstARM32ThreeAddrFP<InstARM32::Vzip>;
template class InstARM32TwoAddrGPR<InstARM32::Movt>;
template class InstARM32UnaryopGPR<InstARM32::Movw, false>;
diff --git a/third_party/subzero/src/IceInstARM32.h b/third_party/subzero/src/IceInstARM32.h
index 89f894d..e31aabc 100644
--- a/third_party/subzero/src/IceInstARM32.h
+++ b/third_party/subzero/src/IceInstARM32.h
@@ -434,18 +434,32 @@
Vcmp,
Vcvt,
Vdiv,
+ Vdup,
Veor,
+ Vldr1d,
+ Vldr1q,
Vmla,
+ Vmlap,
Vmls,
+ Vmovl,
+ Vmovh,
+ Vmovhl,
+ Vmovlh,
Vmrs,
Vmul,
+ Vmulh,
Vmvn,
Vneg,
Vorr,
+ Vqadd,
+ Vqmovn2,
+ Vqsub,
Vshl,
Vshr,
Vsqrt,
- Vsub
+ Vstr1,
+ Vsub,
+ Vzip
};
static constexpr size_t InstSize = sizeof(uint32_t);
@@ -1012,15 +1026,27 @@
using InstARM32Veor = InstARM32ThreeAddrFP<InstARM32::Veor>;
using InstARM32Vmla = InstARM32FourAddrFP<InstARM32::Vmla>;
using InstARM32Vmls = InstARM32FourAddrFP<InstARM32::Vmls>;
+using InstARM32Vmovl = InstARM32ThreeAddrFP<InstARM32::Vmovl>;
+using InstARM32Vmovh = InstARM32ThreeAddrFP<InstARM32::Vmovh>;
+using InstARM32Vmovhl = InstARM32ThreeAddrFP<InstARM32::Vmovhl>;
+using InstARM32Vmovlh = InstARM32ThreeAddrFP<InstARM32::Vmovlh>;
using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>;
using InstARM32Vmvn = InstARM32UnaryopFP<InstARM32::Vmvn>;
using InstARM32Vneg = InstARM32UnaryopSignAwareFP<InstARM32::Vneg>;
using InstARM32Vorr = InstARM32ThreeAddrFP<InstARM32::Vorr>;
+using InstARM32Vqadd = InstARM32ThreeAddrSignAwareFP<InstARM32::Vqadd>;
+using InstARM32Vqsub = InstARM32ThreeAddrSignAwareFP<InstARM32::Vqsub>;
+using InstARM32Vqmovn2 = InstARM32ThreeAddrSignAwareFP<InstARM32::Vqmovn2>;
+using InstARM32Vmulh = InstARM32ThreeAddrSignAwareFP<InstARM32::Vmulh>;
+using InstARM32Vmlap = InstARM32ThreeAddrFP<InstARM32::Vmlap>;
using InstARM32Vshl = InstARM32ThreeAddrSignAwareFP<InstARM32::Vshl>;
using InstARM32Vshr = InstARM32ThreeAddrSignAwareFP<InstARM32::Vshr>;
using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>;
using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>;
using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>;
+using InstARM32Vldr1d = InstARM32LoadBase<InstARM32::Vldr1d>;
+using InstARM32Vldr1q = InstARM32LoadBase<InstARM32::Vldr1q>;
+using InstARM32Vzip = InstARM32ThreeAddrFP<InstARM32::Vzip>;
/// MovT leaves the bottom bits alone so dest is also a source. This helps
/// indicate that a previous MovW setting dest is not dead code.
using InstARM32Movt = InstARM32TwoAddrGPR<InstARM32::Movt>;
@@ -1332,6 +1358,57 @@
OperandARM32Mem *Mem, CondARM32::Cond Predicate);
};
+/// Sub-vector store instruction. It's important for liveness that there is no
+/// Dest operand (OperandARM32Mem instead of Dest Variable).
+class InstARM32Vstr1 final : public InstARM32Pred {
+ InstARM32Vstr1() = delete;
+ InstARM32Vstr1(const InstARM32Vstr1 &) = delete;
+ InstARM32Vstr1 &operator=(const InstARM32Vstr1 &) = delete;
+
+public:
+ /// Value must be a register.
+ static InstARM32Vstr1 *create(Cfg *Func, Variable *Value,
+ OperandARM32Mem *Mem, CondARM32::Cond Predicate,
+ SizeT Size) {
+ return new (Func->allocate<InstARM32Vstr1>())
+ InstARM32Vstr1(Func, Value, Mem, Predicate, Size);
+ }
+ void emit(const Cfg *Func) const override;
+ void emitIAS(const Cfg *Func) const override;
+ void dump(const Cfg *Func) const override;
+ static bool classof(const Inst *Instr) { return isClassof(Instr, Vstr1); }
+
+private:
+ InstARM32Vstr1(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
+ CondARM32::Cond Predicate, SizeT Size);
+
+ SizeT Size;
+};
+
+/// Vector element duplication/replication instruction.
+class InstARM32Vdup final : public InstARM32Pred {
+ InstARM32Vdup() = delete;
+ InstARM32Vdup(const InstARM32Vdup &) = delete;
+ InstARM32Vdup &operator=(const InstARM32Vdup &) = delete;
+
+public:
+ /// Value must be a register.
+ static InstARM32Vdup *create(Cfg *Func, Variable *Dest, Variable *Src,
+ IValueT Idx) {
+ return new (Func->allocate<InstARM32Vdup>())
+ InstARM32Vdup(Func, Dest, Src, Idx);
+ }
+ void emit(const Cfg *Func) const override;
+ void emitIAS(const Cfg *Func) const override;
+ void dump(const Cfg *Func) const override;
+ static bool classof(const Inst *Instr) { return isClassof(Instr, Vdup); }
+
+private:
+ InstARM32Vdup(Cfg *Func, Variable *Dest, Variable *Src, IValueT Idx);
+
+ const IValueT Idx;
+};
+
class InstARM32Trap : public InstARM32 {
InstARM32Trap() = delete;
InstARM32Trap(const InstARM32Trap &) = delete;
@@ -1626,6 +1703,8 @@
template <> void InstARM32Ldr::emit(const Cfg *Func) const;
template <> void InstARM32Movw::emit(const Cfg *Func) const;
template <> void InstARM32Movt::emit(const Cfg *Func) const;
+template <> void InstARM32Vldr1d::emit(const Cfg *Func) const;
+template <> void InstARM32Vldr1q::emit(const Cfg *Func) const;
} // end of namespace ARM32
} // end of namespace Ice
diff --git a/third_party/subzero/src/IceTargetLoweringARM32.cpp b/third_party/subzero/src/IceTargetLoweringARM32.cpp
index 3271271..d820bca 100644
--- a/third_party/subzero/src/IceTargetLoweringARM32.cpp
+++ b/third_party/subzero/src/IceTargetLoweringARM32.cpp
@@ -2442,6 +2442,8 @@
return legalizeToReg(Target, Swapped ? Src0 : Src1);
}
+ Operand *src1() const { return Src1; }
+
protected:
Operand *const Src0;
Operand *const Src1;
@@ -3436,8 +3438,13 @@
_lsl(T, Src0R, Src1R);
}
} else {
- auto *Src1R = Srcs.unswappedSrc1R(this);
- _vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned);
+ if (Srcs.hasConstOperand()) {
+ ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
+ _vshl(T, Src0R, ShAmt);
+ } else {
+ auto *Src1R = Srcs.unswappedSrc1R(this);
+ _vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned);
+ }
}
_mov(Dest, T);
return;
@@ -3455,10 +3462,15 @@
_lsr(T, Src0R, Src1R);
}
} else {
- auto *Src1R = Srcs.unswappedSrc1R(this);
- auto *Src1RNeg = makeReg(Src1R->getType());
- _vneg(Src1RNeg, Src1R);
- _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Unsigned);
+ if (Srcs.hasConstOperand()) {
+ ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
+ _vshr(T, Src0R, ShAmt)->setSignType(InstARM32::FS_Unsigned);
+ } else {
+ auto *Src1R = Srcs.unswappedSrc1R(this);
+ auto *Src1RNeg = makeReg(Src1R->getType());
+ _vneg(Src1RNeg, Src1R);
+ _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Unsigned);
+ }
}
_mov(Dest, T);
return;
@@ -3475,10 +3487,15 @@
_asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this));
}
} else {
- auto *Src1R = Srcs.unswappedSrc1R(this);
- auto *Src1RNeg = makeReg(Src1R->getType());
- _vneg(Src1RNeg, Src1R);
- _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Signed);
+ if (Srcs.hasConstOperand()) {
+ ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
+ _vshr(T, Src0R, ShAmt)->setSignType(InstARM32::FS_Signed);
+ } else {
+ auto *Src1R = Srcs.unswappedSrc1R(this);
+ auto *Src1RNeg = makeReg(Src1R->getType());
+ _vneg(Src1RNeg, Src1R);
+ _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Signed);
+ }
}
_mov(Dest, T);
return;
@@ -5251,7 +5268,6 @@
return;
}
case Intrinsics::Fabs: {
- Type DestTy = Dest->getType();
Variable *T = makeReg(DestTy);
_vabs(T, legalizeToReg(Instr->getArg(0)));
_mov(Dest, T);
@@ -5286,7 +5302,7 @@
assert(isScalarFloatingType(Dest->getType()) ||
getFlags().getApplicationBinaryInterface() != ::Ice::ABI_PNaCl);
Variable *Src = legalizeToReg(Instr->getArg(0));
- Variable *T = makeReg(Dest->getType());
+ Variable *T = makeReg(DestTy);
_vsqrt(T, Src);
_mov(Dest, T);
return;
@@ -5304,14 +5320,121 @@
case Intrinsics::Trap:
_trap();
return;
+ case Intrinsics::AddSaturateSigned:
+ case Intrinsics::AddSaturateUnsigned: {
+ bool Unsigned = (ID == Intrinsics::AddSaturateUnsigned);
+ Variable *Src0 = legalizeToReg(Instr->getArg(0));
+ Variable *Src1 = legalizeToReg(Instr->getArg(1));
+ Variable *T = makeReg(DestTy);
+ _vqadd(T, Src0, Src1, Unsigned);
+ _mov(Dest, T);
+ return;
+ }
case Intrinsics::LoadSubVector: {
- UnimplementedLoweringError(this, Instr);
+ assert(llvm::isa<ConstantInteger32>(Instr->getArg(1)) &&
+ "LoadSubVector second argument must be a constant");
+ Variable *Dest = Instr->getDest();
+ Type Ty = Dest->getType();
+ auto *SubVectorSize = llvm::cast<ConstantInteger32>(Instr->getArg(1));
+ Operand *Addr = Instr->getArg(0);
+ OperandARM32Mem *Src = formMemoryOperand(Addr, Ty);
+ doMockBoundsCheck(Src);
+
+ if (Dest->isRematerializable()) {
+ Context.insert<InstFakeDef>(Dest);
+ return;
+ }
+
+ auto *T = makeReg(Ty);
+ switch (SubVectorSize->getValue()) {
+ case 4:
+ _vldr1d(T, Src);
+ break;
+ case 8:
+ _vldr1q(T, Src);
+ break;
+ default:
+ Func->setError("Unexpected size for LoadSubVector");
+ return;
+ }
+ _mov(Dest, T);
return;
}
case Intrinsics::StoreSubVector: {
+ assert(llvm::isa<ConstantInteger32>(Instr->getArg(2)) &&
+ "StoreSubVector third argument must be a constant");
+ auto *SubVectorSize = llvm::cast<ConstantInteger32>(Instr->getArg(2));
+ Variable *Value = legalizeToReg(Instr->getArg(0));
+ Operand *Addr = Instr->getArg(1);
+ OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType());
+ doMockBoundsCheck(NewAddr);
+
+ Value = legalizeToReg(Value);
+
+ switch (SubVectorSize->getValue()) {
+ case 4:
+ _vstr1d(Value, NewAddr);
+ break;
+ case 8:
+ _vstr1q(Value, NewAddr);
+ break;
+ default:
+ Func->setError("Unexpected size for StoreSubVector");
+ return;
+ }
+ return;
+ }
+ case Intrinsics::MultiplyAddPairs: {
+ Variable *Src0 = legalizeToReg(Instr->getArg(0));
+ Variable *Src1 = legalizeToReg(Instr->getArg(1));
+ Variable *T = makeReg(DestTy);
+ _vmlap(T, Src0, Src1);
+ _mov(Dest, T);
+ return;
+ }
+ case Intrinsics::MultiplyHighSigned:
+ case Intrinsics::MultiplyHighUnsigned: {
+ bool Unsigned = (ID == Intrinsics::MultiplyHighUnsigned);
+ Variable *Src0 = legalizeToReg(Instr->getArg(0));
+ Variable *Src1 = legalizeToReg(Instr->getArg(1));
+ Variable *T = makeReg(DestTy);
+ _vmulh(T, Src0, Src1, Unsigned);
+ _mov(Dest, T);
+ return;
+ }
+ case Intrinsics::Nearbyint: {
UnimplementedLoweringError(this, Instr);
return;
}
+ case Intrinsics::Round: {
+ UnimplementedLoweringError(this, Instr);
+ return;
+ }
+ case Intrinsics::SignMask: {
+ UnimplementedLoweringError(this, Instr);
+ return;
+ }
+ case Intrinsics::SubtractSaturateSigned:
+ case Intrinsics::SubtractSaturateUnsigned: {
+ bool Unsigned = (ID == Intrinsics::SubtractSaturateUnsigned);
+ Variable *Src0 = legalizeToReg(Instr->getArg(0));
+ Variable *Src1 = legalizeToReg(Instr->getArg(1));
+ Variable *T = makeReg(DestTy);
+ _vqsub(T, Src0, Src1, Unsigned);
+ _mov(Dest, T);
+ return;
+ }
+ case Intrinsics::VectorPackSigned:
+ case Intrinsics::VectorPackUnsigned: {
+ bool Unsigned = (ID == Intrinsics::VectorPackUnsigned);
+ bool Saturating = true;
+ Variable *Src0 = legalizeToReg(Instr->getArg(0));
+ Variable *Src1 = legalizeToReg(Instr->getArg(1));
+ Variable *T = makeReg(DestTy);
+ _vqmovn2(T, Src0, Src1, Unsigned, Saturating);
+ _mov(Dest, T);
+ return;
+ }
default: // UnknownIntrinsic
Func->setError("Unexpected intrinsic");
return;
@@ -5852,8 +5975,121 @@
const Type DestTy = Dest->getType();
auto *T = makeReg(DestTy);
+ auto *Src0 = Instr->getSrc(0);
+ auto *Src1 = Instr->getSrc(1);
+ const SizeT NumElements = typeNumElements(DestTy);
+ const Type ElementType = typeElementType(DestTy);
+
+ bool Replicate = true;
+ for (SizeT I = 1; Replicate && I < Instr->getNumIndexes(); ++I) {
+ if (Instr->getIndexValue(I) != Instr->getIndexValue(0)) {
+ Replicate = false;
+ }
+ }
+
+ if (Replicate) {
+ Variable *Src0Var = legalizeToReg(Src0);
+ _vdup(T, Src0Var, Instr->getIndexValue(0));
+ _mov(Dest, T);
+ return;
+ }
switch (DestTy) {
+ case IceType_v8i1:
+ case IceType_v8i16: {
+ static constexpr SizeT ExpectedNumElements = 8;
+ assert(ExpectedNumElements == Instr->getNumIndexes());
+ (void)ExpectedNumElements;
+
+ if (Instr->indexesAre(0, 0, 1, 1, 2, 2, 3, 3)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ _vzip(T, Src0R, Src0R);
+ _mov(Dest, T);
+ return;
+ }
+
+ if (Instr->indexesAre(0, 8, 1, 9, 2, 10, 3, 11)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ Variable *Src1R = legalizeToReg(Src1);
+ _vzip(T, Src0R, Src1R);
+ _mov(Dest, T);
+ return;
+ }
+
+ if (Instr->indexesAre(0, 2, 4, 6, 0, 2, 4, 6)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ _vqmovn2(T, Src0R, Src0R, false, false);
+ _mov(Dest, T);
+ return;
+ }
+ } break;
+ case IceType_v16i1:
+ case IceType_v16i8: {
+ static constexpr SizeT ExpectedNumElements = 16;
+ assert(ExpectedNumElements == Instr->getNumIndexes());
+ (void)ExpectedNumElements;
+
+ if (Instr->indexesAre(0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ _vzip(T, Src0R, Src0R);
+ _mov(Dest, T);
+ return;
+ }
+
+ if (Instr->indexesAre(0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7,
+ 23)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ Variable *Src1R = legalizeToReg(Src1);
+ _vzip(T, Src0R, Src1R);
+ _mov(Dest, T);
+ return;
+ }
+ } break;
+ case IceType_v4i1:
+ case IceType_v4i32:
+ case IceType_v4f32: {
+ static constexpr SizeT ExpectedNumElements = 4;
+ assert(ExpectedNumElements == Instr->getNumIndexes());
+ (void)ExpectedNumElements;
+
+ if (Instr->indexesAre(0, 0, 1, 1)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ _vzip(T, Src0R, Src0R);
+ _mov(Dest, T);
+ return;
+ }
+
+ if (Instr->indexesAre(0, 4, 1, 5)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ Variable *Src1R = legalizeToReg(Src1);
+ _vzip(T, Src0R, Src1R);
+ _mov(Dest, T);
+ return;
+ }
+
+ if (Instr->indexesAre(0, 1, 4, 5)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ Variable *Src1R = legalizeToReg(Src1);
+ _vmovlh(T, Src0R, Src1R);
+ _mov(Dest, T);
+ return;
+ }
+
+ if (Instr->indexesAre(2, 3, 2, 3)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ _vmovhl(T, Src0R, Src0R);
+ _mov(Dest, T);
+ return;
+ }
+
+ if (Instr->indexesAre(2, 3, 6, 7)) {
+ Variable *Src0R = legalizeToReg(Src0);
+ Variable *Src1R = legalizeToReg(Src1);
+ _vmovhl(T, Src1R, Src0R);
+ _mov(Dest, T);
+ return;
+ }
+ } break;
default:
break;
// TODO(jpp): figure out how to properly lower this without scalarization.
@@ -5861,10 +6097,6 @@
// Unoptimized shuffle. Perform a series of inserts and extracts.
Context.insert<InstFakeDef>(T);
- auto *Src0 = Instr->getSrc(0);
- auto *Src1 = Instr->getSrc(1);
- const SizeT NumElements = typeNumElements(DestTy);
- const Type ElementType = typeElementType(DestTy);
for (SizeT I = 0; I < Instr->getNumIndexes(); ++I) {
auto *Index = Instr->getIndex(I);
const SizeT Elem = Index->getValue();
diff --git a/third_party/subzero/src/IceTargetLoweringARM32.h b/third_party/subzero/src/IceTargetLoweringARM32.h
index f6cd66b..a629627 100644
--- a/third_party/subzero/src/IceTargetLoweringARM32.h
+++ b/third_party/subzero/src/IceTargetLoweringARM32.h
@@ -885,21 +885,51 @@
CondARM32::Cond Pred = CondARM32::AL) {
Context.insert<InstARM32Vcmp>(Src0, FpZero, Pred);
}
+ void _vdup(Variable *Dest, Variable *Src, int Idx) {
+ Context.insert<InstARM32Vdup>(Dest, Src, Idx);
+ }
void _veor(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstARM32Veor>(Dest, Src0, Src1);
}
+ void _vldr1d(Variable *Dest, OperandARM32Mem *Addr,
+ CondARM32::Cond Pred = CondARM32::AL) {
+ Context.insert<InstARM32Vldr1d>(Dest, Addr, Pred);
+ }
+ void _vldr1q(Variable *Dest, OperandARM32Mem *Addr,
+ CondARM32::Cond Pred = CondARM32::AL) {
+ Context.insert<InstARM32Vldr1q>(Dest, Addr, Pred);
+ }
void _vmrs(CondARM32::Cond Pred = CondARM32::AL) {
Context.insert<InstARM32Vmrs>(Pred);
}
void _vmla(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstARM32Vmla>(Dest, Src0, Src1);
}
+ void _vmlap(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstARM32Vmlap>(Dest, Src0, Src1);
+ }
void _vmls(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstARM32Vmls>(Dest, Src0, Src1);
}
+ void _vmovl(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstARM32Vmovl>(Dest, Src0, Src1);
+ }
+ void _vmovh(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstARM32Vmovh>(Dest, Src0, Src1);
+ }
+ void _vmovhl(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstARM32Vmovhl>(Dest, Src0, Src1);
+ }
+ void _vmovlh(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstARM32Vmovlh>(Dest, Src0, Src1);
+ }
void _vmul(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstARM32Vmul>(Dest, Src0, Src1);
}
+ void _vmulh(Variable *Dest, Variable *Src0, Variable *Src1, bool Unsigned) {
+ Context.insert<InstARM32Vmulh>(Dest, Src0, Src1)
+ ->setSignType(Unsigned ? InstARM32::FS_Unsigned : InstARM32::FS_Signed);
+ }
void _vmvn(Variable *Dest, Variable *Src0) {
Context.insert<InstARM32Vmvn>(Dest, Src0, CondARM32::AL);
}
@@ -910,6 +940,21 @@
void _vorr(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstARM32Vorr>(Dest, Src0, Src1);
}
+ void _vqadd(Variable *Dest, Variable *Src0, Variable *Src1, bool Unsigned) {
+ Context.insert<InstARM32Vqadd>(Dest, Src0, Src1)
+ ->setSignType(Unsigned ? InstARM32::FS_Unsigned : InstARM32::FS_Signed);
+ }
+ void _vqmovn2(Variable *Dest, Variable *Src0, Variable *Src1, bool Unsigned,
+ bool Saturating) {
+ Context.insert<InstARM32Vqmovn2>(Dest, Src0, Src1)
+ ->setSignType(Saturating ? (Unsigned ? InstARM32::FS_Unsigned
+ : InstARM32::FS_Signed)
+ : InstARM32::FS_None);
+ }
+ void _vqsub(Variable *Dest, Variable *Src0, Variable *Src1, bool Unsigned) {
+ Context.insert<InstARM32Vqsub>(Dest, Src0, Src1)
+ ->setSignType(Unsigned ? InstARM32::FS_Unsigned : InstARM32::FS_Signed);
+ }
InstARM32Vshl *_vshl(Variable *Dest, Variable *Src0, Variable *Src1) {
return Context.insert<InstARM32Vshl>(Dest, Src0, Src1);
}
@@ -925,9 +970,20 @@
CondARM32::Cond Pred = CondARM32::AL) {
Context.insert<InstARM32Vsqrt>(Dest, Src, Pred);
}
+ void _vstr1d(Variable *Value, OperandARM32Mem *Addr,
+ CondARM32::Cond Pred = CondARM32::AL) {
+ Context.insert<InstARM32Vstr1>(Value, Addr, Pred, 32);
+ }
+ void _vstr1q(Variable *Value, OperandARM32Mem *Addr,
+ CondARM32::Cond Pred = CondARM32::AL) {
+ Context.insert<InstARM32Vstr1>(Value, Addr, Pred, 64);
+ }
void _vsub(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstARM32Vsub>(Dest, Src0, Src1);
}
+ void _vzip(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstARM32Vzip>(Dest, Src0, Src1);
+ }
// Iterates over the CFG and determines the maximum outgoing stack arguments
// bytes. This information is later used during addProlog() to pre-allocate
diff --git a/third_party/subzero/src/IceTargetLoweringX86BaseImpl.h b/third_party/subzero/src/IceTargetLoweringX86BaseImpl.h
index c5eac33..f2fd83e 100644
--- a/third_party/subzero/src/IceTargetLoweringX86BaseImpl.h
+++ b/third_party/subzero/src/IceTargetLoweringX86BaseImpl.h
@@ -6304,22 +6304,22 @@
break;
}
- const SizeT Index0 = Instr->getIndex(0)->getValue();
- const SizeT Index1 = Instr->getIndex(1)->getValue();
- const SizeT Index2 = Instr->getIndex(2)->getValue();
- const SizeT Index3 = Instr->getIndex(3)->getValue();
- const SizeT Index4 = Instr->getIndex(4)->getValue();
- const SizeT Index5 = Instr->getIndex(5)->getValue();
- const SizeT Index6 = Instr->getIndex(6)->getValue();
- const SizeT Index7 = Instr->getIndex(7)->getValue();
- const SizeT Index8 = Instr->getIndex(8)->getValue();
- const SizeT Index9 = Instr->getIndex(9)->getValue();
- const SizeT Index10 = Instr->getIndex(10)->getValue();
- const SizeT Index11 = Instr->getIndex(11)->getValue();
- const SizeT Index12 = Instr->getIndex(12)->getValue();
- const SizeT Index13 = Instr->getIndex(13)->getValue();
- const SizeT Index14 = Instr->getIndex(14)->getValue();
- const SizeT Index15 = Instr->getIndex(15)->getValue();
+ const SizeT Index0 = Instr->getIndexValue(0);
+ const SizeT Index1 = Instr->getIndexValue(1);
+ const SizeT Index2 = Instr->getIndexValue(2);
+ const SizeT Index3 = Instr->getIndexValue(3);
+ const SizeT Index4 = Instr->getIndexValue(4);
+ const SizeT Index5 = Instr->getIndexValue(5);
+ const SizeT Index6 = Instr->getIndexValue(6);
+ const SizeT Index7 = Instr->getIndexValue(7);
+ const SizeT Index8 = Instr->getIndexValue(8);
+ const SizeT Index9 = Instr->getIndexValue(9);
+ const SizeT Index10 = Instr->getIndexValue(10);
+ const SizeT Index11 = Instr->getIndexValue(11);
+ const SizeT Index12 = Instr->getIndexValue(12);
+ const SizeT Index13 = Instr->getIndexValue(13);
+ const SizeT Index14 = Instr->getIndexValue(14);
+ const SizeT Index15 = Instr->getIndexValue(15);
lowerShuffleVector_UsingPshufb(Dest, Src0, Src1, Index0, Index1, Index2,
Index3, Index4, Index5, Index6, Index7,
@@ -6376,14 +6376,14 @@
break;
}
- const SizeT Index0 = Instr->getIndex(0)->getValue();
- const SizeT Index1 = Instr->getIndex(1)->getValue();
- const SizeT Index2 = Instr->getIndex(2)->getValue();
- const SizeT Index3 = Instr->getIndex(3)->getValue();
- const SizeT Index4 = Instr->getIndex(4)->getValue();
- const SizeT Index5 = Instr->getIndex(5)->getValue();
- const SizeT Index6 = Instr->getIndex(6)->getValue();
- const SizeT Index7 = Instr->getIndex(7)->getValue();
+ const SizeT Index0 = Instr->getIndexValue(0);
+ const SizeT Index1 = Instr->getIndexValue(1);
+ const SizeT Index2 = Instr->getIndexValue(2);
+ const SizeT Index3 = Instr->getIndexValue(3);
+ const SizeT Index4 = Instr->getIndexValue(4);
+ const SizeT Index5 = Instr->getIndexValue(5);
+ const SizeT Index6 = Instr->getIndexValue(6);
+ const SizeT Index7 = Instr->getIndexValue(7);
#define TO_BYTE_INDEX(I) ((I) << 1)
lowerShuffleVector_UsingPshufb(
@@ -6403,10 +6403,10 @@
case IceType_v4f32: {
static constexpr SizeT ExpectedNumElements = 4;
assert(ExpectedNumElements == Instr->getNumIndexes());
- const SizeT Index0 = Instr->getIndex(0)->getValue();
- const SizeT Index1 = Instr->getIndex(1)->getValue();
- const SizeT Index2 = Instr->getIndex(2)->getValue();
- const SizeT Index3 = Instr->getIndex(3)->getValue();
+ const SizeT Index0 = Instr->getIndexValue(0);
+ const SizeT Index1 = Instr->getIndexValue(1);
+ const SizeT Index2 = Instr->getIndexValue(2);
+ const SizeT Index3 = Instr->getIndexValue(3);
Variable *T = nullptr;
switch (makeSrcSwitchMask(Index0, Index1, Index2, Index3)) {
#define CASE_SRCS_IN(S0, S1, S2, S3) \
@@ -6611,8 +6611,7 @@
InstExtractElement::create(Func, ExtElmt, Src0, Index));
} else {
lowerExtractElement(InstExtractElement::create(
- Func, ExtElmt, Src1,
- Ctx->getConstantInt32(Index->getValue() - NumElements)));
+ Func, ExtElmt, Src1, Ctx->getConstantInt32(Elem - NumElements)));
}
auto *NewT = makeReg(DestTy);
lowerInsertElement(InstInsertElement::create(Func, NewT, T, ExtElmt,
diff --git a/third_party/subzero/src/IceTypes.def b/third_party/subzero/src/IceTypes.def
index da0c7ec..0c9e491 100644
--- a/third_party/subzero/src/IceTypes.def
+++ b/third_party/subzero/src/IceTypes.def
@@ -79,7 +79,7 @@
X(v8i16, 1, 1, 0, 1, 0, 1, v8i1) \
X(v4i32, 1, 1, 0, 1, 0, 1, v4i1) \
X(v4f32, 1, 0, 1, 0, 0, 1, v4i1) \
-//#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsBoolean, IsParam, \
+//#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsBoolean, IsParam,
// CompareResult)
#endif // SUBZERO_SRC_ICETYPES_DEF