Exemple #1
0
bool glPixelBuffer::create(GLushort width, GLushort height, GLushort depth,
                           GFXImageFormat formatEnum,
                           GFXDataFormat dataTypeEnum) {
    GLenum textureTypeEnum = GLUtil::glTextureTypeTable[to_U32(_textureType)];
    _internalFormat = GLUtil::internalFormat(formatEnum, dataTypeEnum, false);
    _format = GLUtil::glImageFormatTable[to_U32(formatEnum)];
    _dataType = GLUtil::glDataFormat[to_U32(dataTypeEnum)];

    Console::printfn(Locale::get(_ID("GL_PB_GEN")), width, height);
    _width = width;
    _height = height;
    _depth = depth;

    _bufferSize = _width * 4;
    switch (_pbtype) {
        case PBType::PB_TEXTURE_2D:
            _bufferSize *= _height;
            break;
        case PBType::PB_TEXTURE_3D:
            _bufferSize *= _height * _depth;
            break;
    };

    switch (_dataType) {
        case GL_SHORT:
        case GL_HALF_FLOAT:
        case GL_UNSIGNED_SHORT:
            _dataSizeBytes = 2;
            break;
        case GL_FLOAT:
        case GL_INT:
        case GL_UNSIGNED_INT:
            _dataSizeBytes = 4;
            break;
        default:
            break;
    }
    _bufferSize *= _dataSizeBytes;

    GL_API::deleteTextures(1, &_textureID, _textureType);

    glCreateTextures(textureTypeEnum, 1, &_textureID);
    glTextureParameteri(_textureID, GL_GENERATE_MIPMAP, 0);
    glTextureParameteri(_textureID, GL_TEXTURE_MIN_FILTER, to_I32(GL_NEAREST));
    glTextureParameteri(_textureID, GL_TEXTURE_MAG_FILTER, to_I32(GL_NEAREST));
    glTextureParameteri(_textureID, GL_TEXTURE_BASE_LEVEL, 0);
    glTextureParameteri(_textureID, GL_TEXTURE_MAX_LEVEL, 1000);
    glTextureParameteri(_textureID, GL_TEXTURE_WRAP_S, to_I32(GL_REPEAT));

    if (_pbtype != PBType::PB_TEXTURE_1D) {
        glTextureParameteri(_textureID, GL_TEXTURE_WRAP_T, to_I32(GL_REPEAT));
    }
    if (_pbtype == PBType::PB_TEXTURE_3D) {
        glTextureParameteri(_textureID, GL_TEXTURE_WRAP_R, to_I32(GL_REPEAT));
    }

    U16 mipLevels = to_U16(std::floor(std::log2(std::max(_width, _height))) + 1);
    GL_API::getStateTracker().setPixelPackUnpackAlignment();
    switch (_pbtype) {
        case PBType::PB_TEXTURE_1D:
            glTextureStorage1D(_textureID, mipLevels, _internalFormat, _width);
            break;
        case PBType::PB_TEXTURE_2D:
            glTextureStorage2D(_textureID, mipLevels, _internalFormat, _width, _height);
            break;
        case PBType::PB_TEXTURE_3D:
            glTextureStorage3D(_textureID, mipLevels, _internalFormat, _width, _height, _depth);
            break;
    };

    if (_pixelBufferHandle > 0) {
        GLUtil::freeBuffer(_pixelBufferHandle);
    }

    GLUtil::createAndAllocBuffer(_bufferSize, GL_STREAM_DRAW, _pixelBufferHandle, NULL, _name.empty() ? nullptr : _name.c_str());

    return _pixelBufferHandle != 0 && _textureID != 0;
}
Exemple #2
0
/**
 * Do error-check tests for a non-mipmapped texture.
 */
static bool
test_one_level_errors(GLenum target)
{
	const GLint width = 64, height = 4, depth = 8;
	GLuint tex;
	GLint v;

	assert(target == GL_TEXTURE_1D ||
	       target == GL_TEXTURE_2D ||
	       target == GL_TEXTURE_3D);

	glCreateTextures(target, 1, &tex);
	glBindTextureUnit(0, tex);

	if (target == GL_TEXTURE_1D) {
		glTextureStorage1D(tex, 1, GL_RGBA8, width);
	} else if (target == GL_TEXTURE_2D) {
		glTextureStorage2D(tex, 1, GL_RGBA8, width, height);
	} else if (target == GL_TEXTURE_3D) {
		glTextureStorage3D(tex, 1, GL_RGBA8, width, height, depth);
	}

	piglit_check_gl_error(GL_NO_ERROR);

	glGetTextureLevelParameteriv(tex, 0, GL_TEXTURE_WIDTH, &v);
	if (v != width) {
		printf("%s: bad width: %d, should be %d\n", TestName, v, width);
		return false;
	}

	if (target != GL_TEXTURE_1D) {
		glGetTextureLevelParameteriv(tex, 0, GL_TEXTURE_HEIGHT, &v);
		if (v != height) {
			printf("%s: bad height: %d, should be %d\n", TestName,
			       v, height);
			return false;
		}
	}

	if (target == GL_TEXTURE_3D) {
		glGetTextureLevelParameteriv(tex, 0, GL_TEXTURE_DEPTH, &v);
		if (v != depth) {
			printf("%s: bad depth: %d, should be %d\n", TestName,
			       v, depth);
			return false;
		}
	}

	/* The ARB_texture_storage spec says:
	 *
	 *     "Using any of the following commands with the same texture will
	 *     result in the error INVALID_OPERATION being generated, even if
	 *     it does not affect the dimensions or format:
	 *
	 *         - TexImage*
	 *         - CompressedTexImage*
	 *         - CopyTexImage*
	 *         - TexStorage*"
	 */
	if (!piglit_khr_no_error && target == GL_TEXTURE_2D) {
		glTexImage2D(target, 0, GL_RGBA, width, height, 0,
			     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
		if (glGetError() != GL_INVALID_OPERATION) {
			printf("%s: glTexImage2D failed to generate error\n",
			       TestName);
			return false;
		}

		glTextureStorage2D(tex, 1, GL_RGBA8, width, height);
		if (glGetError() != GL_INVALID_OPERATION) {
			printf("%s: glTextureStorage2D() failed to generate "
			       "error\n", TestName);
			return false;
		}

		glCopyTexImage2D(target, 0, GL_RGBA, 0, 0, width, height, 0);
		if (glGetError() != GL_INVALID_OPERATION) {
			printf("%s: glCopyTexImage2D() failed to generate "
			       "error\n", TestName);
			return false;
		}
	}

	glDeleteTextures(1, &tex);

	return true;
}
Exemple #3
0
	void OGLTexture1D::CreateHWResource(ArrayRef<ElementInitData> init_data, float4 const * clear_value_hint)
	{
		KFL_UNUSED(clear_value_hint);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		if (sample_count_ <= 1)
		{
			uint32_t const pbo_size = mipmap_start_offset_.back() * array_size_;
			if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
			{
				glTextureParameteri(texture_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

				glNamedBufferStorage(pbo_, pbo_size, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);

				uint32_t const w0 = this->Width(0);

				if (array_size_ > 1)
				{
					glTextureStorage2D(texture_, num_mip_maps_, glinternalFormat, w0, array_size_);
				}
				else
				{
					glTextureStorage1D(texture_, num_mip_maps_, glinternalFormat, w0);
				}

				if (!init_data.empty())
				{
					for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
					{
						for (uint32_t level = 0; level < num_mip_maps_; ++ level)
						{
							uint32_t const w = this->Width(level);
							GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data;

							if (IsCompressedFormat(format_))
							{
								uint32_t const block_size = NumFormatBytes(format_) * 4;
								GLsizei const image_size = ((w + 3) / 4) * block_size;

								if (array_size_ > 1)
								{
									glCompressedTextureSubImage2D(texture_, level, 0, array_index,
										w, 1, glformat, image_size, data);
								}
								else
								{
									glCompressedTextureSubImage1D(texture_, level, 0,
										w, glformat, image_size, data);
								}
							}
							else
							{
								if (array_size_ > 1)
								{
									glTextureSubImage2D(texture_, level, 0, array_index, w, 1,
										glformat, gltype, data);
								}
								else
								{
									glTextureSubImage1D(texture_, level, 0, w, glformat, gltype, data);
								}
							}
						}
					}
				}
			}
			else
			{
				auto& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
				
				re.BindTexture(0, target_type_, texture_);
				glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_);
				if (glloader_GL_VERSION_4_4() || glloader_GL_ARB_buffer_storage())
				{
					glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_DYNAMIC_STORAGE_BIT);
				}
				else
				{
					glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_STREAM_COPY);
				}
				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

				if (glloader_GL_VERSION_4_2() || glloader_GL_ARB_texture_storage())
				{
					uint32_t const w0 = this->Width(0);

					if (array_size_ > 1)
					{
						glTexStorage2D(target_type_, num_mip_maps_, glinternalFormat, w0, array_size_);
					}
					else
					{
						glTexStorage1D(target_type_, num_mip_maps_, glinternalFormat, w0);
					}

					if (!init_data.empty())
					{
						for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
						{
							for (uint32_t level = 0; level < num_mip_maps_; ++ level)
							{
								uint32_t const w = this->Width(level);
								GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data;

								if (IsCompressedFormat(format_))
								{
									uint32_t const block_size = NumFormatBytes(format_) * 4;
									GLsizei const image_size = ((w + 3) / 4) * block_size;

									if (array_size_ > 1)
									{
										glCompressedTexSubImage2D(target_type_, level, 0, array_index,
											w, 1, glformat, image_size, data);
									}
									else
									{
										glCompressedTexSubImage1D(target_type_, level, 0,
											w, glformat, image_size, data);
									}
								}
								else
								{
									if (array_size_ > 1)
									{
										glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, gltype, data);
									}
									else
									{
										glTexSubImage1D(target_type_, level, 0, w, glformat, gltype, data);
									}
								}
							}
						}
					}
				}
				else
				{
					for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
					{
						for (uint32_t level = 0; level < num_mip_maps_; ++ level)
						{
							uint32_t const w = this->Width(level);

							if (IsCompressedFormat(format_))
							{
								uint32_t const block_size = NumFormatBytes(format_) * 4;
								GLsizei const image_size = ((w + 3) / 4) * block_size;

								if (array_size_ > 1)
								{
									if (0 == array_index)
									{
										glCompressedTexImage2D(target_type_, level, glinternalFormat,
											w, array_size_, 0, image_size * array_size_, nullptr);
									}

									if (!init_data.empty())
									{
										glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, image_size, init_data[array_index * num_mip_maps_ + level].data);
									}
								}
								else
								{
									glCompressedTexImage1D(target_type_, level, glinternalFormat,
										w, 0, image_size,
										init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
								}
							}
							else
							{
								if (array_size_ > 1)
								{
									if (0 == array_index)
									{
										glTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, glformat, gltype, nullptr);
									}

									if (!init_data.empty())
									{
										glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
									}
								}
								else
								{
									glTexImage1D(target_type_, level, glinternalFormat, w, 0, glformat, gltype,
										init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
								}
							}
						}
					}
				}
			}
		}
		else
		{
			glBindRenderbuffer(GL_RENDERBUFFER, texture_);
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, sample_count_, glinternalFormat, width_, 1);
		}

		hw_res_ready_ = true;
	}
Exemple #4
0
/**
 * Do error-check tests for a mipmapped texture.
 */
static bool
test_mipmap_errors(GLenum target)
{
	GLint width = 128, height = 64, depth = 4, levels = 8;
	const char *targetString = piglit_get_gl_enum_name(target);
	GLuint tex;
	GLint v, l;

	assert(target == GL_TEXTURE_1D ||
	       target == GL_TEXTURE_2D ||
	       target == GL_TEXTURE_3D);

	glCreateTextures(target, 1, &tex);
	glBindTextureUnit(0, tex);

	if (target == GL_TEXTURE_1D) {
		glTextureStorage1D(tex, levels, GL_RGBA8, width);
	} else if (target == GL_TEXTURE_2D) {
		glTextureStorage2D(tex, levels, GL_RGBA8, width, height);
	} else if (target == GL_TEXTURE_3D) {
		glTextureStorage3D(tex, levels, GL_RGBA8, width, 
			height, depth);
	}

	piglit_check_gl_error(GL_NO_ERROR);

	glGetTextureParameteriv(tex, GL_TEXTURE_IMMUTABLE_FORMAT, &v);
	if (!v) {
		printf("%s: %s GL_TEXTURE_IMMUTABLE_FORMAT query returned "
		       "false\n",
		       TestName, targetString);
		return false;
	}

	for (l = 0; l < levels; l++) {
		glGetTextureLevelParameteriv(tex, l, GL_TEXTURE_WIDTH, &v);
		if (v != width) {
			printf("%s: %s level %d: bad width: %d, should be %d\n",
			       TestName, targetString, l, v, width);
			return false;
		}

		if (target != GL_TEXTURE_1D) {
			glGetTextureLevelParameteriv(tex, l, 
						     GL_TEXTURE_HEIGHT, &v);
			if (v != height) {
				printf("%s: %s level %d: bad height: %d, "
				       "should be %d\n",
				       TestName, targetString, l, v, height);
				return false;
			}
		}

		if (target == GL_TEXTURE_3D) {
			glGetTextureLevelParameteriv(tex, l, 
						     GL_TEXTURE_DEPTH, &v);
			if (v != depth) {
				printf("%s: %s level %d: bad depth: %d, "
				       "should be %d\n",
				       TestName, targetString, l, v, depth);
				return false;
			}
		}

		if (width > 1)
			width /= 2;
		if (height > 1)
			height /= 2;
		if (depth > 1)
			depth /= 2;
	}

	glDeleteTextures(1, &tex);

	return true;
}