Грешка при липса на памет на OpenGL при превишаване на 128MB текстури

Работя върху вградено OpenGL графично приложение, работещо на Intel Atom z530 с графичен хардуер GMA500. (Разбрах, че GMA500 е PowerVR под капака, но не съм сигурен). Работя с драйвера Tungsten Graphics "Gallium" на Ubuntu 9.10 Karmic Koala. О, трябва също да знаете, че имам 1 GB налична системна памет.

Ето го проблемът: имам код, който разпределя куп 512x512x32 текстури (около 1MB всяка). Когато стигна до около 118-120 от тях, получавам грешка „недостиг на памет“ от OpenGL и също получавам това съобщение на конзолата: „грешка: INTEL_ESCAPE_ALLOC_REGION неуспешно“.

Това, заедно с прости измервания, докато гледам "отгоре", ми показва, че достигам ограничение от ~128MB за текстури. Странното е следното: тази архитектура няма специална видео памет, тя е споделена. И мога да кажа със сигурност, че OpenGL използва системна памет за текстурите, защото виждам, че „безплатната“ памет отива надолу в „отгоре“. Така че защо да получавам грешка „недостиг на памет“? Бих очаквал opengl просто да използва повече от наличната ми системна памет. Защо ще има такава твърда граница? Има ли някакъв начин да промените на какво е зададено това очевидно „твърдо ограничение“?

Благодаря! Крис


Ето изхода ми от glxinfo:

$ glxinfo

name of display: :0.0
display: :0  screen: 0
direct rendering: Yes
server glx vendor string: SGI
server glx version string: 1.2
server glx extensions:
    GLX_ARB_multisample, GLX_EXT_visual_info, GLX_EXT_visual_rating, 
    GLX_EXT_import_context, GLX_EXT_texture_from_pixmap, GLX_OML_swap_method, 
    GLX_SGI_make_current_read, GLX_SGIS_multisample, GLX_SGIX_hyperpipe, 
    GLX_SGIX_swap_barrier, GLX_SGIX_fbconfig, GLX_MESA_copy_sub_buffer
client glx vendor string: SGI
client glx version string: 1.4
client glx extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context, 
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_MESA_allocate_memory, 
    GLX_MESA_copy_sub_buffer, GLX_MESA_swap_control, 
    GLX_MESA_swap_frame_usage, GLX_OML_swap_method, GLX_OML_sync_control, 
    GLX_SGI_make_current_read, GLX_SGI_swap_control, GLX_SGI_video_sync, 
    GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, 
    GLX_SGIX_visual_select_group, GLX_EXT_texture_from_pixmap
GLX version: 1.2
GLX extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context, 
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_MESA_swap_control, 
    GLX_OML_swap_method, GLX_SGI_make_current_read, GLX_SGIS_multisample, 
    GLX_SGIX_fbconfig, GLX_EXT_texture_from_pixmap
OpenGL vendor string: Tungsten Graphics, Inc.
OpenGL renderer string: Gallium 0.1, pipe/psb/Poulsbo on IEGD
OpenGL version string: 2.0 Mesa 7.1
OpenGL shading language version string: 1.10
OpenGL extensions:
    GL_ARB_depth_texture, GL_ARB_draw_buffers, GL_ARB_fragment_program, 
    GL_ARB_fragment_shader, GL_ARB_multisample, GL_ARB_multitexture, 
    GL_ARB_occlusion_query, GL_ARB_pixel_buffer_object, 
    GL_ARB_point_parameters, GL_ARB_point_sprite, GL_ARB_shader_objects, 
    GL_ARB_shading_language_100, GL_ARB_shading_language_120, GL_ARB_shadow, 
    GL_ARB_texture_border_clamp, GL_ARB_texture_compression, 
    GL_ARB_texture_cube_map, GL_ARB_texture_env_add, 
    GL_ARB_texture_env_combine, GL_ARB_texture_env_crossbar, 
    GL_ARB_texture_env_dot3, GL_ARB_texture_mirrored_repeat, 
    GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle, 
    GL_ARB_transpose_matrix, GL_ARB_vertex_buffer_object, 
    GL_ARB_vertex_program, GL_ARB_vertex_shader, GL_ARB_window_pos, 
    GL_EXT_abgr, GL_EXT_bgra, GL_EXT_blend_color, 
    GL_EXT_blend_equation_separate, GL_EXT_blend_func_separate, 
    GL_EXT_blend_logic_op, GL_EXT_blend_minmax, GL_EXT_blend_subtract, 
    GL_EXT_clip_volume_hint, GL_EXT_compiled_vertex_array, 
    GL_EXT_copy_texture, GL_EXT_draw_range_elements, 
    GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, GL_EXT_fog_coord, 
    GL_EXT_multi_draw_arrays, GL_EXT_packed_pixels, 
    GL_EXT_pixel_buffer_object, GL_EXT_point_parameters, 
    GL_EXT_polygon_offset, GL_EXT_rescale_normal, GL_EXT_secondary_color, 
    GL_EXT_separate_specular_color, GL_EXT_shadow_funcs, 
    GL_EXT_stencil_two_side, GL_EXT_stencil_wrap, GL_EXT_subtexture, 
    GL_EXT_texture, GL_EXT_texture3D, GL_EXT_texture_compression_s3tc, 
    GL_EXT_texture_edge_clamp, GL_EXT_texture_env_add, 
    GL_EXT_texture_env_combine, GL_EXT_texture_env_dot3, 
    GL_EXT_texture_filter_anisotropic, GL_EXT_texture_lod_bias, 
    GL_EXT_texture_mirror_clamp, GL_EXT_texture_object, 
    GL_EXT_texture_rectangle, GL_EXT_vertex_array, GL_APPLE_packed_pixels, 
    GL_ATI_blend_equation_separate, GL_ATI_separate_stencil, 
    GL_IBM_rasterpos_clip, GL_IBM_texture_mirrored_repeat, 
    GL_INGR_blend_func_separate, GL_MESA_ycbcr_texture, GL_MESA_window_pos, 
    GL_NV_blend_square, GL_NV_light_max_exponent, GL_NV_point_sprite, 
    GL_NV_texture_rectangle, GL_NV_texgen_reflection, GL_OES_read_format, 
    GL_SGI_color_matrix, GL_SGIS_generate_mipmap, 
    GL_SGIS_texture_border_clamp, GL_SGIS_texture_edge_clamp, 
    GL_SGIS_texture_lod, GL_SUN_multi_draw_arrays

    ...truncated visuals part...

person sidewinderguy    schedule 12.01.2011    source източник
comment
Можете ли да копирате и поставите резултата от командата glxinfo? (редовете преди визуалния масив)   -  person tibur    schedule 13.01.2011
comment
Само странична бележка: OpenGL често поддържа текстури в RAM, за да може бързо да променя текстурите в GPU-RAM. Така че не можете да използвате увеличеното използване на RAM като индикатор за no-dedicated-texture-ram. (Вярвам, че това може да се заобиколи с помощта на буфери. Говореше се за добавяне на разширения за текстури само за GPU)   -  person Macke    schedule 13.01.2011
comment
MESA не е ли само софтуерен рендер? (моят opengl-linux-fu е малко слаб..)   -  person Macke    schedule 13.01.2011
comment
Мисля, че в този случай мога. От една страна, няма GPU-RAM с този хардуер, това е споделена RAM, така че GPU винаги използва системна RAM. Освен това внимателно измерих използването на системната RAM памет и то съвпада много близо с теоретичния размер на тези текстури.   -  person sidewinderguy    schedule 13.01.2011
comment
Да, MESA е софтуерен растеризатор. Аз обаче не използвам MESA - погледнете низа на доставчика и низа на рендера. ;-)   -  person sidewinderguy    schedule 13.01.2011
comment
@Marcus: Mesa има софтуерен растеризатор, да, но има и множество хардуерни драйвери.   -  person genpfault    schedule 13.01.2011


Отговори (3)


Споделената видео памет не означава, че цялата налична RAM може да се използва за текстури. Обикновено графичният модул получава само част от системната памет, която изобщо не е достъпна за останалата част от системата. Във вашия случай това може да е 128MiB. Това нещо като AGP апертурата, използвана от вградената графика на чипсета, или размера на кадровия буфер на интегрираната графика на Intel Core.

Тъй като OpenGL декларира чисто виртуален обектен модел, той трябва да пази копие на всеки обект в "постоянна" памет (съдържанието на паметта на графичния процесор може да бъде анулирано по всяко време, например от VT превключватели, нулиране на графичния процесор и подобни неща), това е какво се консумира от обикновената системна памет.

person datenwolf    schedule 12.01.2011
comment
В моя случай GPU определено използва обикновена системна памет за текстури. Виждам, че наличната оперативна памет отива надолу в „отгоре“, докато създавам текстурите. Ако графичният процесор използваше памет, която не беше достъпна за останалата част от системата, тогава нямаше да видя свободната RAM да пада в „отгоре“. (И BTW, намалява точно с количеството, което бих очаквал, така че това не се дължи на друго използване на паметта в приложението ми). - person sidewinderguy; 13.01.2011
comment
Мисля обаче, че сте прав за GPU, който получава фиксирана част от системната памет. Просто ми се иска да мога да кажа на шофьора да използва повече по някакъв начин... - person sidewinderguy; 14.01.2011
comment
@sidewinderguy: Паметта, която виждате изразходвана допълнително към среза на GPU, е backingstore на OpenGL драйвера. Съдържанието на паметта на графичния процесор (текстури, обекти на върхови буфери, FBO и т.н.) може да бъде изхвърлено, например ако системата е превключена към друга X11 сесия. Или ако поставите системата в хибернация – при събуждане графичният процесор се нулира и съдържанието на среза с памет на графичния процесор се поврежда. OpenGL обаче трябва да гарантира, че приложенията могат да използват своите обекти по всяко време. Така че има копие на всеки обект, съхранявано в системната памет. - person datenwolf; 14.01.2011

Използвайте по-малки или компресирани текстури или палетизирани. Също така внимавайте относно списъците с геометрия/дисплей, които също изсмукват GPU ресурси.

(Можете сами да направите търсенето на палитрата в шейдър, ако вашата GL реализация не поддържа такива текстури.)

person Macke    schedule 12.01.2011
comment
По-малко би било добре, но трябва да поддържам определено ниво на детайлност. Обмислях компресирани текстури и те звучат добре, но по-бавни ли са за рисуване и/или изобразяване? Имам много ограничена производителност на CPU/GPU. Добра гледна точка за списъците за показване... Ще трябва да опитам да стартирам без тях и да видя дали имам някаква полза. - person sidewinderguy; 13.01.2011
comment
Никога не съм използвал палетизирани текстури, те също толкова ли са бързи за рисуване/изобразяване като нормалните текстури? Заемат ли значително по-малко памет? - person sidewinderguy; 13.01.2011
comment
Това ме навежда на въпроса: как бихте могли да имате 120 текстури от 512x512 и да ги показвате в пълна разделителна способност? - person tibur; 13.01.2011
comment
@sidewinderguy: Те са по-бавни поради търсенето на палитра за всеки пиксел, но ако се придържате към 256 цвята, те са една трета от размера в сравнение с 8-битовите RGB текстури. - person Macke; 13.01.2011
comment
@Marcus: Забавянето е нежелателно. Въпреки това, едно интересно нещо за моето приложение е, че наистина се нуждая само от около 5 или 6 цвята, така че вероятно бих могъл да постигна огромни спестявания в използването на паметта. - person sidewinderguy; 13.01.2011
comment
@tibur: Всички тези текстури са плочки, съдържащи някои изображения, които ще бъдат показани като част от 3D карта. Така че не всички се показват едновременно, зависи от вашето панорамиране/мащабиране кои плочки виждате и с каква разделителна способност. - person sidewinderguy; 13.01.2011
comment
@sidewinderguy: Всъщност не е възможно да се спуснат под 8-битови текстури (е, с много математика можете да опаковате две 4-битови текстури в една и да изберете всяка с помощта на шейдър... но това е просто глупаво). Но ако 8-битовите няма да ви отведат там, може би бихте могли да помислите за динамично управление на вашите mipmaps (тъй като не използвате всички текстури през цялото време). Помислете за Google Earth. Това е по-сложно, но се мащабира по-добре и не пречи толкова много на останалата част от приложението ви. - person Macke; 13.01.2011
comment
@sidewinderguy компресираните DXT текстури са още по-бързи за рисуване, поради по-доброто използване на кеша. Декодирането се извършва изцяло в TMU. Съвременните чипове вече не поддържат палетизирани текстури - драйверът ще декомпресира до 32 бита, преди да ги зареди. - person Axel Gneiting; 13.01.2011
comment
Компресията звучи страхотно! Трябва обаче да знаете, че за моето конкретно приложение създавам всички текстури по време на изпълнение (начертавайки ги с помощта на FBO). Въпросът ми е мога ли да рисувам в компресирана текстура? Ако е така, това ще бъде ли бавно/бързо? - person sidewinderguy; 14.01.2011
comment
Между другото, благодаря за дискусиите относно битовата дълбочина/и т.н. Това ме накара да осъзная, че е нелепо да използвам 32-битови текстури (рисувам плътни цветове в тях и не ми трябват много цветове). Преминах на 16-битов и това помага много. - person sidewinderguy; 14.01.2011

Взехте ли предвид копията с по-ниска разделителна способност на текстурата, които се създават, за да извършват mipmapping?

предварително изчислени, оптимизирани колекции от изображения, които придружават основната текстура, предназначени да увеличат скоростта на изобразяване и да намалят артефактите на псевдонимите.

Те намаляват на стъпки от степен 2, така че ще имате 256x256, 128x128, 64x64, ... изображение, придружаващо основната текстура. Това ще изяде вашата текстурна памет много по-бързо, отколкото ако имате само едно изображение.

В примера, който използват в Wikipedia, оригиналната текстура е 256x256 и те свеждат текстурите на mip-map до 1x1. По техни изчисления

Увеличението на пространството за съхранение, необходимо за всички тези mipmaps, е една трета от оригиналната текстура

Това предполага, че не сте го изключили, разбира се.

Що се отнася до това как да увеличите количеството памет, до което можете да имате достъп - съжалявам, нямам представа.

person ChrisF    schedule 12.01.2011
comment
Но това води само до 1/4 + 1/16 + 1/64 + ... ‹ 1/2 повече използвана памет, така че все още трябва да е под 192MB - person brian_d; 13.01.2011
comment
@brian_d - мина известно време, откакто направих тези неща, така че математиката ми е малко ръждясала. - person ChrisF; 13.01.2011
comment

решихме проблема, като дефинирахме ViewModels (изпуснахме свойството Language, защото беше премахнато от модела, но същият случай се отнася за ParentAccount) и контролера, както следва:

public class AccountEdit
{
    public int Id { get; set; }
    [Required]
    [LocalizedDisplayName("Name")]
    public string Name { get; set; }
    [LocalizedDisplayName("ParentAccount")]
    public int ParentAccount { get; set; }
    [LocalizedDisplayName("Role")]
    public Role Role { get; set; }

    public AccountEdit() { }

    public AccountEdit(Account a)
    {
        Id = a.Id;
        Name = a.Name;
        ParentAccount = a.ParentAccount!=null ? a.ParentAccount.Id : 0;
        Role = a.Role;
    }

    public Account BoundAccount()
    {
        DataAccessObject<Account> dao = new DataAccessObject<Account>();
        Account account = dao.Get(Id);
        account.Name = Name;
        if (ParentAccount == default(int))
            account.ParentAccount = null;
        else
            account.ParentAccount = dao.Get(ParentAccount);
        return account;
    }
}

    [HttpPost]
    [NeedsPersistence]
    public ActionResult CreateDistributor(DistributorCreate dc)
    {
        if (ModelState.IsValid)
        {
            Account account = dc.BoundAccount();
            accountDao.Save(account, currentUser);
            return RedirectToAction("Index");
        }
        else {
            return View(dc);
        }
    }
- person sidewinderguy; 13.01.2011
comment
@sidewiderguy - Съжалявам, че не мога да си спомня (мина известно време) и мисля, че това може да е проблемът. Всяка от вашите текстури всъщност заема приблизително 1,36 MB. Разделянето на 128 на 1,36 дава приблизително 94, което обаче е по-ниско от вашето преброяване от 118. - person ChrisF; 13.01.2011
comment
Не използвайте gluBuild2DMipmaps или не използвайте opengl.org/registry/specs /SGIS/generate_mipmap.txt. Изглежда означава, че не използвате mipmaps... - person tibur; 13.01.2011
comment
@ChrisF: Истинският ми проблем не е да разбера защо мога да получа само 118 разпределени текстури. Истинският проблем е как да направя повече RAM достъпна за мен. Независимо от това, благодаря за приноса относно тези неща за mipmapping, ще го имам предвид и съм сигурен, че ще помогне. - person sidewinderguy; 13.01.2011
comment
@sidewinderguy - Ах. Наистина се занимавах с този момент, така че защо да получавам грешка „недостиг на памет“? - тъй като изглеждаше объркан защо паметта ти е свършила, преди да мислиш, че трябва. - person ChrisF; 13.01.2011
comment
@ChrisF - Добре, съжалявам за неяснотата :-) - person sidewinderguy; 13.01.2011