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

时间:2019-04-15 16:25:22

标签: c++ debugging visual-studio-debugging directx-9 allegro5

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

我正在运行Windows 10。

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

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

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

以下是可测试的快板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的失败调用,这些调用在allegro的源代码中的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或其他方法进行调试的所有提示。

编辑 我尝试过的事情的最新消息。

在重新构建快板时,在包含d3d9.h之前定义D3D_DEBUG_INFO似乎没有任何作用。

在dxcpl中启用DirectX调试输出无济于事。

尝试通过PIX运行我的应用程序会导致不兼容错误。它说Directx子版本在应用程序和pix运行时之间不匹配。如何为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

盗墓贼

1 个答案:

答案 0 :(得分:1)

我对该主题进行的每次搜索都返回了相同的3个解决方案:
-驱动程序错误,更新或降级
-错误的DirectX安装,他们在Microsoft论坛中要求他们卸载DirectX,删除该根注册表项,然后重新安装DirectX
-很多人指出,当D3D结构部分初始化而没有提供完全初始化的结构时会发生这种情况。

如果有更多信息,我会回来。