Видеопамять OS X из сборки x86_64 - PullRequest
1 голос
/ 21 марта 2011

Я работаю над приложением C ++ на Intel Mac OS X 10.6.x.У меня есть переменная, которая содержит данные пикселей, которые были получены с помощью вызова OpenGL glReadPixels.Я хочу сделать некоторые операции непосредственно с данными пикселей, используя инструкции по сборке x86_64.Процедура сборки отлично работает в тестовых программах, но когда я пытаюсь использовать ее для данных пикселей, она получает только нули в той области памяти, на которую указывает переменная данных пикселей.Я предполагаю, что это потому, что я пытаюсь получить доступ к видеопамяти непосредственно из сборки x86_64.Есть ли способ получить доступ к видеопамяти x86_64 напрямую из сборки?Иначе как я могу разрешить эту ситуацию?

Цените любые указатели.Заранее спасибо.

См. Ниже пример кода, чтобы перевернуть последние n и первые n байтов.Тот же код хорошо работает в тестовой программе.

void Flip(void *b, unsigned int w, unsigned int h)
  {
    __asm {
    mov r8, rdi //rdi b
    mov r9, rsi //W
    mov r10,rdx //H
    mov r11, 0 // h <- 0
    mov r12, 0 // w<- 0
    outloop:
    ------------
    .............
    .............
  }

1 Ответ

5 голосов
/ 21 марта 2011

Это не совсем ответ, но бит комментариев слишком короток, чтобы опубликовать это.

Ваша встроенная сборка проблематична несколькими способами:

  • , что предполагаетКогда компилятор попадает во встроенный блок, аргументы функции все еще находятся в регистрах arg.Это не гарантируется.
  • используется встроенная сборка в стиле MS-VC ++;Я не уверен насчет OSX Clang, но собственно gcc отказывается даже компилировать это.

Было бы также хорошо иметь полный (компилируемый) фрагмент исходного кода.Что-то вроде (32-битный код):

int mogrifyFramebufferContents(unsigned char *fb, int width, int height)
{
    int i, sum;
    glReadPixels(1, 1, width, height, GL_RGBA, GL_UNSIGNED_BYTE, fb);
    for (i = 0, sum = 0; i < 4 * width * height; i++)
        sum += fb[i];

    printf("sum over fb via C: %d\n", sum);

    asm("xorl     %0, %0\n"
        "xorl     %1, %1\n"
        "0:\n"
        "movsbl   (%2, %1), %ebx\n"
        "addl     %ebx, %0\n"
        "incl     %1\n"
        "cmpl     %1, %3\n"
        "jl       0b"
        : "=r"(sum)
        : "r"(i), "r"(fb), "r"(4 * width * height)
        : "cc", "%ebx");

    printf("sum over fb via inline asm: %d\n", sum);

    return (sum);
}

Если я не допустил однократную ошибку, этот код должен привести к одинаковому выводу для C и сборки.Попробуйте что-то похожее, прямо в том месте, где вы получаете доступ к прочитанным данным в C, и сравните результаты сборки - или даже пошагово сгенерированную сборку с помощью отладчика.дать вам отправную точку для того, что означают заполнители %0 ... %2, и / или как работают ограничения присвоения регистра, такие как "=r"(sum) выше.

...