d3d-> CreateDevice中的D3DERR_INVALIDCALL导致Allegro 5 D3D程序启动时窗口闪烁

问题描述 投票:4回答:1

在创建启用了多采样的Allegro 5 Direct3D窗口时,我正在调试窗口创建闪烁。我已经将问题缩小到了allegro的d3d_disp.cpp源文件中的窗口创建。但是,我无法从DirectX获得任何调试输出。闪烁仅发生在D3D模式(不是OpenGL)中,并且仅在启用多采样时发生。另外需要注意的是,这只发生在NVIDIA gpus上运行程序时,而不是在集成的Intel上运行。

我正在运行Windows 10。

我已经尝试在Visual Studio 2017中调试它,但它不捕获DX的调试输出。我从2010年6月开始安装DirectX SDK时安装了DirectX调试符号。

我已经尝试重建allegro并链接到gcc中的libd3dx9d.a,但我仍然无法进入directx函数调用并且未加载符号。在MinGW-W64 GCC 8.1或2010年6月的DirectX SDK中,没有libd3d9d.a(请注意调试用的d)库。

我尝试通过PIX运行我的程序,但它给了我一个我无法解决的不兼容错误。

这是可测试的例子allegro 5代码:

#include <allegro5/allegro.h>
#include <allegro5/allegro_color.h>
#include <allegro5/allegro_primitives.h> 
#include <allegro5/allegro_direct3d.h>

#include <cstdio>
#include <climits>

int main(int argc, char **argv) {

    if (!al_init()) { return 1; }
    al_init_primitives_addon();
    al_install_keyboard();

    ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue();
    if (!queue) { return 2; }
    al_register_event_source(queue, al_get_keyboard_event_source());

    al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE);
    al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);

    bool use_opengl = false;
    if (use_opengl) {
        al_set_new_display_flags(ALLEGRO_OPENGL);
    }
    else {
        al_set_new_display_flags(ALLEGRO_DIRECT3D);
    }
    ALLEGRO_DISPLAY *display = al_create_display(1024, 600);
    if (!display) { return 2; }
    if (use_opengl) {
        al_set_window_title(display, "OpenGL window");
    }
    else {
        al_set_window_title(display, "Direct3D window");
    }
    al_register_event_source(queue, al_get_display_event_source(display));


    al_clear_to_color(al_color_name("black"));
    al_draw_circle(500, 300, 200, al_color_name("white"), 5.0);
    al_draw_line(200, 200, 700, 300, al_color_name("white"), 5.0);
    al_flip_display();

    bool quit = false;
    while (!quit) {
        ALLEGRO_EVENT ev;
        al_wait_for_event(queue, &ev);
        if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { quit = true; }
        if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { quit = true; }
    }
    return 0;
}

理想情况下,窗口在创建时不会闪烁。有许多程序使用Direct3D,不会在窗口创建时闪烁。

我已经把这个问题缩小到d3d-> CreateDevice失败的调用,在这里的divrc源代码中的src \ win \ d3d_disp.cpp中返回D3DERR_INVALIDCALL:https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L812-L837

我需要帮助从DirectX获取调试输出,到目前为止没有任何工作。有关使用DirectX9,VS 2017(和/或)MinGW-W64 GCC 8.1和GDB或其他方法进行调试的任何提示均表示赞赏。

编辑关于我尝试过的事情的更新。

在重建allegro之前,在包含d3d9.h之前定义D3D_DEBUG_INFO似乎没有做任何事情。

在dxcpl中启用DirectX调试输出没有做任何事情。

尝试通过PIX运行我的应用程序会导致不兼容错误。它说应用程序和pix运行时之间的directx颠倒不匹配。如何构建特定版本的DirectX dll?

我发现当通过D3D_PRESENT_PARAMETERS启用多重采样时,交换效果必须是D3DSWAPEFFECT_DISCARD。修正了,没有任何改变。

仍然得到D3DERR_INVALIDCALL。我无法在未初始化的演示参数中看到任何内容。

如果我无法启用DirectX调试输出,我真的不知道为什么会发生此错误。

调试提示欢迎。我可以看到窗口创建在成功之前多次失败,这就是窗口闪烁的原因。

EDIT2这似乎是指定BackBufferFormat的一个问题,因为这是成功创建窗口和失败之间的唯一区别。

EDIT3 BackBufferFormat很好。真正的区别在于尝试多次采样的质量水平。按照

https://github.com/liballeg/allegro5/blob/master/src/win/d3d_display_formats.cpp#L95

CheckDeviceMultiSampleType

有一个错误导致它试图设置一个关闭的质量水平。质量等级表示计数,而不是最大指数。

闪烁消失了,但还需要进行更多测试。

至于补充问题,如何使用DirectX启用调试信息?我所做的一切都没有按照上述方式发挥作用。我会给那些可以帮助我实现D3D和DX调试输出的人奖励答案。

@Gull_Code如果你愿意,可以在这里克隆我的allegro测试分支:

https://github.com/EdgarReynaldo/allegro5/tree/test

Bugsquasher

c++ debugging visual-studio-debugging directx-9 allegro5
1个回答
1
投票

我对该主题所做的每次搜索都返回了相同的3个解决方案: -Bad驱动程序,更新或降级 -Bad directx安装,在microsoft论坛中他们要求那个人卸载directx,删除root注册表项,重新安装directx -A很多人指出,当D3D结构部分初始化而没有给出完全初始化的结构时会发生这种情况...... 如果我有更多的信息,我会回来的。

© www.soinside.com 2019 - 2024. All rights reserved.