You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
781 lines
20 KiB
781 lines
20 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES Utilities
|
|
* ------------------------------------------------
|
|
*
|
|
* Copyright 2014 The Android Open Source Project
|
|
*
|
|
* 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.
|
|
*
|
|
*//*!
|
|
* \file
|
|
* \brief Render context implementation that does no rendering.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "tcuNullRenderContext.hpp"
|
|
#include "tcuTexture.hpp"
|
|
#include "tcuTextureUtil.hpp"
|
|
#include "deThreadLocal.hpp"
|
|
#include "gluRenderConfig.hpp"
|
|
#include "gluTextureUtil.hpp"
|
|
#include "glwEnums.hpp"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace tcu
|
|
{
|
|
namespace null
|
|
{
|
|
|
|
using namespace glw;
|
|
|
|
#include "tcuNullRenderContextFuncs.inl"
|
|
|
|
using namespace glu;
|
|
using std::string;
|
|
using std::vector;
|
|
|
|
class ObjectManager
|
|
{
|
|
public:
|
|
ObjectManager (void)
|
|
: m_lastObject(0)
|
|
{
|
|
}
|
|
|
|
deUint32 allocate (void)
|
|
{
|
|
deUint32 object = ++m_lastObject;
|
|
if (object == 0)
|
|
object = ++m_lastObject; // Just ignore overflow.
|
|
return object;
|
|
}
|
|
|
|
void free (deUint32 object)
|
|
{
|
|
DE_UNREF(object);
|
|
}
|
|
|
|
private:
|
|
deUint32 m_lastObject;
|
|
};
|
|
|
|
class Context
|
|
{
|
|
public:
|
|
Context (ContextType ctxType_);
|
|
~Context (void);
|
|
|
|
private:
|
|
Context (const Context&);
|
|
Context& operator= (const Context&);
|
|
|
|
void addExtension (const char* name);
|
|
|
|
public:
|
|
// GL state exposed to implementation functions.
|
|
const ContextType ctxType;
|
|
|
|
string vendor;
|
|
string version;
|
|
string renderer;
|
|
string shadingLanguageVersion;
|
|
string extensions;
|
|
vector<string> extensionList;
|
|
vector<deUint32> compressedTextureList;
|
|
|
|
GLenum lastError;
|
|
|
|
int pixelPackRowLength;
|
|
int pixelPackSkipRows;
|
|
int pixelPackSkipPixels;
|
|
int pixelPackAlignment;
|
|
|
|
GLuint pixelPackBufferBufferBinding;
|
|
|
|
ObjectManager shaders;
|
|
ObjectManager programs;
|
|
ObjectManager textures;
|
|
ObjectManager buffers;
|
|
ObjectManager renderbuffers;
|
|
ObjectManager framebuffers;
|
|
ObjectManager samplers;
|
|
ObjectManager vertexArrays;
|
|
ObjectManager queries;
|
|
ObjectManager transformFeedbacks;
|
|
ObjectManager programPipelines;
|
|
};
|
|
|
|
Context::Context (ContextType ctxType_)
|
|
: ctxType (ctxType_)
|
|
, vendor ("drawElements")
|
|
, renderer ("dummy")
|
|
, lastError (GL_NO_ERROR)
|
|
, pixelPackRowLength (0)
|
|
, pixelPackSkipRows (0)
|
|
, pixelPackSkipPixels (0)
|
|
, pixelPackAlignment (0)
|
|
, pixelPackBufferBufferBinding (0)
|
|
{
|
|
using glu::ApiType;
|
|
|
|
if (ctxType.getAPI() == ApiType::es(2, 0))
|
|
{
|
|
version = "OpenGL ES 2.0";
|
|
shadingLanguageVersion = "OpenGL ES GLSL ES 1.0";
|
|
}
|
|
else if (ctxType.getAPI() == ApiType::es(3, 0))
|
|
{
|
|
version = "OpenGL ES 3.0";
|
|
shadingLanguageVersion = "OpenGL ES GLSL ES 3.0";
|
|
}
|
|
else if (ctxType.getAPI() == ApiType::es(3, 1))
|
|
{
|
|
version = "OpenGL ES 3.1";
|
|
shadingLanguageVersion = "OpenGL ES GLSL ES 3.1";
|
|
addExtension("GL_OES_texture_stencil8");
|
|
addExtension("GL_OES_sample_shading");
|
|
addExtension("GL_OES_sample_variables");
|
|
addExtension("GL_OES_shader_multisample_interpolation");
|
|
addExtension("GL_OES_shader_image_atomic");
|
|
addExtension("GL_OES_texture_storage_multisample_2d_array");
|
|
addExtension("GL_KHR_blend_equation_advanced");
|
|
addExtension("GL_KHR_blend_equation_advanced_coherent");
|
|
addExtension("GL_EXT_shader_io_blocks");
|
|
addExtension("GL_EXT_geometry_shader");
|
|
addExtension("GL_EXT_geometry_point_size");
|
|
addExtension("GL_EXT_tessellation_shader");
|
|
addExtension("GL_EXT_tessellation_point_size");
|
|
addExtension("GL_EXT_gpu_shader5");
|
|
addExtension("GL_EXT_shader_implicit_conversions");
|
|
addExtension("GL_EXT_texture_buffer");
|
|
addExtension("GL_EXT_texture_cube_map_array");
|
|
addExtension("GL_EXT_draw_buffers_indexed");
|
|
addExtension("GL_EXT_texture_sRGB_decode");
|
|
addExtension("GL_EXT_texture_border_clamp");
|
|
addExtension("GL_KHR_debug");
|
|
addExtension("GL_EXT_primitive_bounding_box");
|
|
addExtension("GL_ANDROID_extension_pack_es31a");
|
|
addExtension("GL_EXT_copy_image");
|
|
}
|
|
else if (ctxType.getAPI() == ApiType::es(3, 2))
|
|
{
|
|
version = "OpenGL ES 3.2";
|
|
shadingLanguageVersion = "OpenGL ES GLSL ES 3.2";
|
|
}
|
|
else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 3)
|
|
{
|
|
version = "3.3.0";
|
|
shadingLanguageVersion = "3.30";
|
|
}
|
|
else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() <= 4)
|
|
{
|
|
version = "4.4.0";
|
|
shadingLanguageVersion = "4.40";
|
|
}
|
|
else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() == 5)
|
|
{
|
|
version = "4.5.0";
|
|
shadingLanguageVersion = "4.50";
|
|
}
|
|
else if (glu::isContextTypeGLCore(ctxType) && ctxType.getMajorVersion() == 4 && ctxType.getMinorVersion() == 6)
|
|
{
|
|
version = "4.6.0";
|
|
shadingLanguageVersion = "4.60";
|
|
}
|
|
else
|
|
throw tcu::NotSupportedError("Unsupported GL version", "", __FILE__, __LINE__);
|
|
|
|
if (isContextTypeES(ctxType))
|
|
{
|
|
addExtension("GL_EXT_color_buffer_float");
|
|
addExtension("GL_EXT_color_buffer_half_float");
|
|
}
|
|
|
|
// support compressed formats
|
|
{
|
|
static deUint32 compressedFormats[] =
|
|
{
|
|
GL_ETC1_RGB8_OES,
|
|
GL_COMPRESSED_R11_EAC,
|
|
GL_COMPRESSED_SIGNED_R11_EAC,
|
|
GL_COMPRESSED_RG11_EAC,
|
|
GL_COMPRESSED_SIGNED_RG11_EAC,
|
|
GL_COMPRESSED_RGB8_ETC2,
|
|
GL_COMPRESSED_SRGB8_ETC2,
|
|
GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
|
|
GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
|
|
GL_COMPRESSED_RGBA8_ETC2_EAC,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
|
|
GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
|
|
GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
|
|
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
|
|
};
|
|
|
|
addExtension("GL_KHR_texture_compression_astc_hdr");
|
|
addExtension("GL_KHR_texture_compression_astc_ldr");
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(compressedFormats); ++ndx)
|
|
compressedTextureList.push_back(compressedFormats[ndx]);
|
|
}
|
|
}
|
|
|
|
Context::~Context (void)
|
|
{
|
|
}
|
|
|
|
void Context::addExtension (const char* name)
|
|
{
|
|
if (!extensions.empty())
|
|
extensions += " ";
|
|
extensions += name;
|
|
|
|
extensionList.push_back(name);
|
|
}
|
|
|
|
static de::ThreadLocal s_currentCtx;
|
|
|
|
void setCurrentContext (Context* context)
|
|
{
|
|
s_currentCtx.set((void*)context);
|
|
}
|
|
|
|
Context* getCurrentContext (void)
|
|
{
|
|
return (Context*)s_currentCtx.get();
|
|
}
|
|
|
|
GLW_APICALL GLenum GLW_APIENTRY glGetError (void)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
const GLenum lastErr = ctx->lastError;
|
|
|
|
ctx->lastError = GL_NO_ERROR;
|
|
|
|
return lastErr;
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGetIntegerv (GLenum pname, GLint* params)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
switch (pname)
|
|
{
|
|
case GL_NUM_EXTENSIONS:
|
|
*params = (int)ctx->extensionList.size();
|
|
break;
|
|
|
|
case GL_MAX_VERTEX_ATTRIBS:
|
|
*params = 32;
|
|
break;
|
|
|
|
case GL_MAX_DRAW_BUFFERS:
|
|
case GL_MAX_COLOR_ATTACHMENTS:
|
|
*params = 8;
|
|
break;
|
|
|
|
case GL_MAX_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS:
|
|
case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS:
|
|
*params = 32;
|
|
break;
|
|
|
|
case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS:
|
|
case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
|
|
*params = 8;
|
|
break;
|
|
|
|
case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS:
|
|
case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
|
|
*params = 8;
|
|
break;
|
|
|
|
case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
|
|
*params = 1u << 25;
|
|
break;
|
|
|
|
case GL_MAX_GEOMETRY_OUTPUT_VERTICES:
|
|
*params = 256;
|
|
break;
|
|
|
|
case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
|
|
*params = 2048;
|
|
break;
|
|
|
|
case GL_MAX_GEOMETRY_SHADER_INVOCATIONS:
|
|
*params = 4;
|
|
break;
|
|
|
|
case GL_MAX_COLOR_TEXTURE_SAMPLES:
|
|
*params = 8;
|
|
break;
|
|
|
|
case GL_MAX_TEXTURE_SIZE:
|
|
case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
|
|
case GL_MAX_3D_TEXTURE_SIZE:
|
|
case GL_MAX_RENDERBUFFER_SIZE:
|
|
case GL_MAX_TEXTURE_BUFFER_SIZE:
|
|
*params = 2048;
|
|
break;
|
|
|
|
case GL_MAX_ARRAY_TEXTURE_LAYERS:
|
|
*params = 128;
|
|
break;
|
|
|
|
case GL_NUM_SHADER_BINARY_FORMATS:
|
|
*params = 0;
|
|
break;
|
|
|
|
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
|
*params = (int)ctx->compressedTextureList.size();
|
|
break;
|
|
|
|
case GL_COMPRESSED_TEXTURE_FORMATS:
|
|
deMemcpy(params, &ctx->compressedTextureList[0], ctx->compressedTextureList.size()*sizeof(deUint32));
|
|
break;
|
|
|
|
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
|
|
*params = 16;
|
|
break;
|
|
|
|
case GL_MAX_UNIFORM_BUFFER_BINDINGS:
|
|
*params = 32;
|
|
break;
|
|
|
|
case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
|
|
*params = 16;
|
|
break;
|
|
|
|
case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
|
|
*params = GL_RGBA;
|
|
break;
|
|
|
|
case GL_IMPLEMENTATION_COLOR_READ_TYPE:
|
|
*params = GL_UNSIGNED_BYTE;
|
|
break;
|
|
|
|
case GL_SAMPLE_BUFFERS:
|
|
*params = 0;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params)
|
|
{
|
|
switch (pname)
|
|
{
|
|
case GL_SHADER_COMPILER:
|
|
*params = GL_TRUE;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGetFloatv (GLenum pname, GLfloat* params)
|
|
{
|
|
switch (pname)
|
|
{
|
|
case GL_ALIASED_LINE_WIDTH_RANGE:
|
|
case GL_ALIASED_POINT_SIZE_RANGE:
|
|
params[0] = 0.0f;
|
|
params[1] = 64.0f;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
|
|
{
|
|
static const int s_sampleCounts[] = { 16, 8, 4, 2, 1 };
|
|
|
|
DE_UNREF(internalformat);
|
|
DE_UNREF(target);
|
|
|
|
switch (pname)
|
|
{
|
|
case GL_NUM_SAMPLE_COUNTS:
|
|
if (bufSize >= 1)
|
|
*params = DE_LENGTH_OF_ARRAY(s_sampleCounts);
|
|
break;
|
|
|
|
case GL_SAMPLES:
|
|
deMemcpy(params, s_sampleCounts, de::min(bufSize, DE_LENGTH_OF_ARRAY(s_sampleCounts)));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetString (GLenum name)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
switch (name)
|
|
{
|
|
case GL_VENDOR: return (const glw::GLubyte*)ctx->vendor.c_str();
|
|
case GL_VERSION: return (const glw::GLubyte*)ctx->version.c_str();
|
|
case GL_RENDERER: return (const glw::GLubyte*)ctx->renderer.c_str();
|
|
case GL_SHADING_LANGUAGE_VERSION: return (const glw::GLubyte*)ctx->shadingLanguageVersion.c_str();
|
|
case GL_EXTENSIONS: return (const glw::GLubyte*)ctx->extensions.c_str();
|
|
default:
|
|
ctx->lastError = GL_INVALID_ENUM;
|
|
return DE_NULL;
|
|
}
|
|
}
|
|
|
|
GLW_APICALL const glw::GLubyte* GLW_APIENTRY glGetStringi (GLenum name, GLuint index)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (name == GL_EXTENSIONS)
|
|
{
|
|
if ((size_t)index < ctx->extensionList.size())
|
|
return (const glw::GLubyte*)ctx->extensionList[index].c_str();
|
|
else
|
|
{
|
|
ctx->lastError = GL_INVALID_VALUE;
|
|
return DE_NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ctx->lastError = GL_INVALID_ENUM;
|
|
return DE_NULL;
|
|
}
|
|
}
|
|
|
|
GLW_APICALL GLuint GLW_APIENTRY glCreateProgram ()
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
return (GLuint)ctx->programs.allocate();
|
|
}
|
|
|
|
GLW_APICALL GLuint GLW_APIENTRY glCreateShader (GLenum type)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
DE_UNREF(type);
|
|
return (GLuint)ctx->shaders.allocate();
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params)
|
|
{
|
|
DE_UNREF(shader);
|
|
|
|
if (pname == GL_COMPILE_STATUS)
|
|
*params = GL_TRUE;
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params)
|
|
{
|
|
DE_UNREF(program);
|
|
|
|
if (pname == GL_LINK_STATUS)
|
|
*params = GL_TRUE;
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenTextures (GLsizei n, GLuint* textures)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (textures)
|
|
{
|
|
for (int ndx = 0; ndx < n; ndx++)
|
|
textures[ndx] = ctx->textures.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenQueries (GLsizei n, GLuint* ids)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (ids)
|
|
{
|
|
for (int ndx = 0; ndx < n; ndx++)
|
|
ids[ndx] = ctx->queries.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (buffers)
|
|
{
|
|
for (int ndx = 0; ndx < n; ndx++)
|
|
buffers[ndx] = ctx->buffers.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (renderbuffers)
|
|
{
|
|
for (int ndx = 0; ndx < n; ndx++)
|
|
renderbuffers[ndx] = ctx->renderbuffers.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (framebuffers)
|
|
{
|
|
for (int ndx = 0; ndx < n; ndx++)
|
|
framebuffers[ndx] = ctx->framebuffers.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (arrays)
|
|
{
|
|
for (int ndx = 0; ndx < n; ndx++)
|
|
arrays[ndx] = ctx->vertexArrays.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (samplers)
|
|
{
|
|
for (int ndx = 0; ndx < count; ndx++)
|
|
samplers[ndx] = ctx->samplers.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (ids)
|
|
{
|
|
for (int ndx = 0; ndx < n; ndx++)
|
|
ids[ndx] = ctx->transformFeedbacks.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glGenProgramPipelines (GLsizei n, GLuint* pipelines)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (pipelines)
|
|
{
|
|
for (int ndx = 0; ndx < n; ndx++)
|
|
pipelines[ndx] = ctx->programPipelines.allocate();
|
|
}
|
|
}
|
|
|
|
GLW_APICALL GLvoid* GLW_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
DE_UNREF(target);
|
|
DE_UNREF(offset);
|
|
DE_UNREF(length);
|
|
DE_UNREF(access);
|
|
|
|
if (ctx->lastError == GL_NO_ERROR)
|
|
ctx->lastError = GL_INVALID_OPERATION;
|
|
|
|
return (GLvoid*)0;
|
|
}
|
|
|
|
GLW_APICALL GLenum GLW_APIENTRY glCheckFramebufferStatus (GLenum target)
|
|
{
|
|
DE_UNREF(target);
|
|
return GL_FRAMEBUFFER_COMPLETE;
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
|
|
{
|
|
DE_UNREF(x);
|
|
DE_UNREF(y);
|
|
|
|
Context* const ctx = getCurrentContext();
|
|
const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f); // black
|
|
const tcu::TextureFormat transferFormat = glu::mapGLTransferFormat(format, type);
|
|
|
|
// invalid formats
|
|
if (transferFormat.order == TextureFormat::CHANNELORDER_LAST || transferFormat.type == TextureFormat::CHANNELTYPE_LAST)
|
|
{
|
|
if (ctx->lastError == GL_NO_ERROR)
|
|
ctx->lastError = GL_INVALID_ENUM;
|
|
return;
|
|
}
|
|
|
|
// unsupported formats
|
|
if (!(format == GL_RGBA && type == GL_UNSIGNED_BYTE) &&
|
|
!(format == GL_RGBA_INTEGER && type == GL_INT) &&
|
|
!(format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT) &&
|
|
!(format == GL_RGBA && type == GL_FLOAT))
|
|
{
|
|
if (ctx->lastError == GL_NO_ERROR)
|
|
ctx->lastError = GL_INVALID_ENUM;
|
|
return;
|
|
}
|
|
|
|
// invalid arguments
|
|
if (width < 0 || height < 0)
|
|
{
|
|
if (ctx->lastError == GL_NO_ERROR)
|
|
ctx->lastError = GL_INVALID_OPERATION;
|
|
return;
|
|
}
|
|
|
|
// read to buffer
|
|
if (ctx->pixelPackBufferBufferBinding)
|
|
return;
|
|
|
|
// read to use pointer
|
|
{
|
|
const int targetRowLength = (ctx->pixelPackRowLength != 0) ? (ctx->pixelPackRowLength) : (width);
|
|
const int targetSkipRows = ctx->pixelPackSkipRows;
|
|
const int targetSkipPixels = ctx->pixelPackSkipPixels;
|
|
const int infiniteHeight = targetSkipRows + height; // as much as needed
|
|
const int targetRowPitch = (ctx->pixelPackAlignment == 0) ? (targetRowLength * transferFormat.getPixelSize()) : (deAlign32(targetRowLength * transferFormat.getPixelSize(), ctx->pixelPackAlignment));
|
|
|
|
// Create access to the whole copy target
|
|
const tcu::PixelBufferAccess targetAccess (transferFormat, targetRowLength, infiniteHeight, 1, targetRowPitch, 0, pixels);
|
|
|
|
// Select (skip_pixels, skip_rows, width, height) subregion from it. Clip to horizontal boundaries
|
|
const tcu::PixelBufferAccess targetRectAccess = tcu::getSubregion(targetAccess,
|
|
de::clamp(targetSkipPixels, 0, targetAccess.getWidth()-1),
|
|
targetSkipRows,
|
|
de::clamp(width, 0, de::max(0, targetAccess.getWidth() - targetSkipPixels)),
|
|
height);
|
|
|
|
tcu::clear(targetRectAccess, clearColor);
|
|
}
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glBindBuffer (GLenum target, GLuint buffer)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
if (target == GL_PIXEL_PACK_BUFFER)
|
|
ctx->pixelPackBufferBufferBinding = buffer;
|
|
}
|
|
|
|
GLW_APICALL void GLW_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers)
|
|
{
|
|
Context* const ctx = getCurrentContext();
|
|
|
|
for (GLsizei ndx = 0; ndx < n; ++ndx)
|
|
if (buffers[ndx] && buffers[ndx] == ctx->pixelPackBufferBufferBinding)
|
|
ctx->pixelPackBufferBufferBinding = 0;
|
|
}
|
|
|
|
GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name)
|
|
{
|
|
DE_UNREF(program);
|
|
return (GLint)(deStringHash(name) & 0x7FFFFFFF);
|
|
}
|
|
|
|
void initFunctions (glw::Functions* gl)
|
|
{
|
|
# include "tcuNullRenderContextInitFuncs.inl"
|
|
}
|
|
|
|
static tcu::RenderTarget toRenderTarget (const RenderConfig& renderCfg)
|
|
{
|
|
const int width = getValueOrDefault(renderCfg, &RenderConfig::width, 256);
|
|
const int height = getValueOrDefault(renderCfg, &RenderConfig::height, 256);
|
|
const int redBits = getValueOrDefault(renderCfg, &RenderConfig::redBits, 8);
|
|
const int greenBits = getValueOrDefault(renderCfg, &RenderConfig::greenBits, 8);
|
|
const int blueBits = getValueOrDefault(renderCfg, &RenderConfig::blueBits, 8);
|
|
const int alphaBits = getValueOrDefault(renderCfg, &RenderConfig::alphaBits, 8);
|
|
const int depthBits = getValueOrDefault(renderCfg, &RenderConfig::depthBits, 24);
|
|
const int stencilBits = getValueOrDefault(renderCfg, &RenderConfig::stencilBits, 8);
|
|
const int numSamples = getValueOrDefault(renderCfg, &RenderConfig::numSamples, 0);
|
|
|
|
return tcu::RenderTarget(width, height, tcu::PixelFormat(redBits, greenBits, blueBits, alphaBits), depthBits, stencilBits, numSamples);
|
|
}
|
|
|
|
RenderContext::RenderContext (const RenderConfig& renderCfg)
|
|
: m_ctxType (renderCfg.type)
|
|
, m_renderTarget (toRenderTarget(renderCfg))
|
|
, m_context (DE_NULL)
|
|
{
|
|
m_context = new Context(m_ctxType);
|
|
|
|
initFunctions(&m_functions);
|
|
setCurrentContext(m_context);
|
|
}
|
|
|
|
RenderContext::~RenderContext (void)
|
|
{
|
|
setCurrentContext(DE_NULL);
|
|
delete m_context;
|
|
}
|
|
|
|
void RenderContext::postIterate (void)
|
|
{
|
|
}
|
|
|
|
void RenderContext::makeCurrent (void)
|
|
{
|
|
}
|
|
|
|
} // null
|
|
} // tcu
|