Ошибка OpenGL нехватки памяти при превышении 128 МБ текстур

Я работаю над встроенным графическим приложением OpenGL, работающим на Intel Atom z530 с графическим оборудованием GMA500. (Насколько я понимаю, GMA500 — это PowerVR под капотом, но я не уверен). Я использую драйвер Tungsten Graphics «Gallium» на Ubuntu 9.10 Karmic Koala. О, вы также должны знать, что у меня есть 1 ГБ доступной системной памяти.

Вот проблема: у меня есть код, который выделяет кучу текстур 512x512x32 (около 1 МБ каждая). Когда я добираюсь до 118-120 из них, я получаю сообщение об ошибке «недостаточно памяти» от OpenGL, а также это сообщение на консоли: «ошибка: INTEL_ESCAPE_ALLOC_REGION failed».

Это, наряду с простыми измерениями при взгляде на «верх», указывает мне, что я достиг предела ~ 128 МБ для текстур. Странно вот что: в этой архитектуре нет выделенной видеопамяти, она общая. И я могу точно сказать, что 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 часто хранит текстуры в ОЗУ, чтобы иметь возможность быстро менять текстуры в ОЗУ GPU. Таким образом, вы не можете использовать повышенное использование оперативной памяти в качестве индикатора отсутствия выделенной текстурной оперативной памяти. (Я полагаю, что это можно обойти с помощью буферов. Были разговоры о добавлении расширений для текстур только для графического процессора)   -  person Macke    schedule 13.01.2011
comment
Разве MESA не является чисто программным рендерером? (мой opengl-linux-fu немного слаб ..)   -  person Macke    schedule 13.01.2011
comment
Я думаю, в этом случае я могу. Во-первых, в этом оборудовании нет GPU-RAM, это общая RAM, поэтому GPU всегда использует системную 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)


Общая видеопамять не означает, что всю доступную оперативную память можно использовать для текстур. Обычно графическому блоку достается только часть системной памяти, которая вообще недоступна для остальной системы. В вашем случае это может быть 128 МБ. Это то же самое, что и апертура AGP, используемая встроенной графикой чипсета, или размер буфера кадра интегрированной графики Intel Core.

Поскольку OpenGL объявляет чисто виртуальную объектную модель, он должен хранить копию каждого объекта в «постоянной» памяти (содержимое памяти графического процессора может быть аннулировано в любое время, например, с помощью переключателей VT, сбросов графического процессора и т. д.), это что потребляется из обычной системной памяти.

person datenwolf    schedule 12.01.2011
comment
В моем случае GPU определенно использует обычную системную память для текстур. Я вижу, что доступная оперативная память опускается в «верх», когда я создаю текстуры. Если бы графический процессор использовал память, недоступную для остальной части системы, я бы не увидел, как свободная оперативная память опускается в «верхнюю часть». (И, кстати, он снижается ровно на ту сумму, которую я ожидал, так что это не связано с другим использованием памяти в моем приложении). - person sidewinderguy; 13.01.2011
comment
Однако я думаю, что вы правы в том, что GPU получает фиксированный кусок системной памяти. Я просто хотел бы сказать водителю, чтобы он как-то использовал больше... - person sidewinderguy; 14.01.2011
comment
@sidewinderguy: Память, которую вы видите, потребляемая в дополнение к фрагменту графического процессора, является резервным хранилищем драйвера OpenGL. Содержимое памяти графического процессора (текстуры, объекты буфера вершин, FBO и т. д.) может быть уничтожено, например, если система переключится на другой сеанс X11. Или, если вы переводите систему в спящий режим — при пробуждении GPU сбрасывается, а содержимое слайса памяти GPU повреждается. Однако OpenGL должен гарантировать, что приложения могут использовать свои объекты в любое время. Таким образом, в системной памяти хранится копия каждого объекта. - person datenwolf; 14.01.2011

Используйте более мелкие или сжатые текстуры или паллетированные. Также будьте осторожны со списками геометрии/отображения, которые также потребляют ресурсы графического процессора.

(Вы можете самостоятельно выполнить поиск палитры в шейдере, если ваша реализация 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-бит не даст вам этого, возможно, вы могли бы подумать о динамическом управлении вашими мип-картами (поскольку вы не используете все текстуры все время). Вспомните Google Планета Земля. Это сложнее, но лучше масштабируется и не так сильно мешает остальной части вашего приложения. - 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

Приняли ли вы во внимание копии текстуры с более низким разрешением, которые создаются для выполнения мипмэппинга?

предварительно рассчитанные оптимизированные наборы изображений, которые сопровождают основную текстуру, предназначенные для увеличения скорости рендеринга и уменьшения артефактов сглаживания.

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

В примере, который они используют в Википедии, исходная текстура имеет размер 256x256, а текстуры мип-карты полностью уменьшены до 1x1. По их расчетам

Увеличение объема памяти, необходимого для всех этих MIP-карт, составляет треть исходной текстуры.

Это предполагает, что вы, конечно, не выключили его.

Что касается того, как вы увеличиваете объем памяти, к которой у вас есть доступ, извините, понятия не имею.

person ChrisF    schedule 12.01.2011
comment
Но это приводит только к 1/4 + 1/16 + 1/64 + ... ‹ Используется на 1/2 больше памяти, поэтому она все еще должна быть меньше 192 МБ. - person brian_d; 13.01.2011
comment
@brian_d - я давно не занимался этим, поэтому моя математика немного заржавела. - person ChrisF; 13.01.2011
comment
Хорошая мысль о мипмаппинге. Я определенно должен отключить его, если он еще не отключен (есть идеи, как это сделать в opengl? ;-) -- Проблема в том, что даже с такой возможной экономией мне понадобится больше оперативной памяти (я надеюсь на 512 МБ). - person sidewinderguy; 13.01.2011
comment
@sidewiderguy - извините, я не могу вспомнить (это было давно), и я думаю, что проблема может быть в этом. Каждая из ваших текстур на самом деле занимает примерно 1,36 МБ. Разделив 128 на 1,36, вы получите примерно 94, что, однако, меньше вашего счета 118. - person ChrisF; 13.01.2011
comment
Не используйте gluBuild2DMipmaps или не используйте opengl.org/registry/specs /SGIS/generate_mipmap.txt. Кажется, это означает, что вы не используете мипмапы... - person tibur; 13.01.2011
comment
@ChrisF: Моя настоящая проблема не в том, чтобы понять, почему я смог выделить только 118 текстур. Настоящая проблема заключается в том, как мне сделать больше оперативной памяти доступной для меня. В любом случае, спасибо за вклад в этот материал с мипмаппингом, я буду помнить об этом и уверен, что это поможет. - person sidewinderguy; 13.01.2011
comment
@sidewinderguy - А. Я действительно обращался к этому биту. Так почему я должен получить ошибку «недостаточно памяти»? - поскольку вы казались сбитыми с толку тем, почему у вас закончилась память, прежде чем вы думали, что должны были. - person ChrisF; 13.01.2011
comment
@ChrisF - Верно, извините за двусмысленность :-) - person sidewinderguy; 13.01.2011