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; }
/** * 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; }
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; }
/** * 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; }