How can I define Anti-Aliasing when creating a device in DX9?

Started by
3 comments, last by Juliean 5 months, 3 weeks ago

I am working on a Directx 9 ready project. First of all, my device creation code is as follows:

int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate)
{
    int iRet = CREATE_OK;

    Destroy();

    ms_iWidth   = iHres;
    ms_iHeight  = iVres;

    ms_hWnd     = hWnd;
    ms_hDC      = GetDC(hWnd);
    ms_lpd3d    = Direct3DCreate9(D3D_SDK_VERSION);

    if (!ms_lpd3d)
        return CREATE_NO_DIRECTX;

    if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice))
        return CREATE_ENUM;

    if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
        return CREATE_DETECT;

    std::string stDevList;
    ms_kD3DDetector.GetString(&stDevList);

    //Tracen(stDevList.c_str());
    //Tracenf("adapter %d, device %d, mode %d", ms_iD3DAdapterInfo, ms_iD3DDevInfo, ms_iD3DModeInfo);

    D3D_CAdapterInfo * pkD3DAdapterInfo = ms_kD3DDetector.GetD3DAdapterInfop(ms_iD3DAdapterInfo);
    if (!pkD3DAdapterInfo)
    {
        Tracenf("adapter %d is EMPTY", ms_iD3DAdapterInfo);
        return CREATE_DETECT;
    }

    if (__IsInDriverBlackList(*pkD3DAdapterInfo))
    {
        iRet |= CREATE_BAD_DRIVER;
        __WarningMessage(hWnd, CREATE_BAD_DRIVER);
    }

    D3D_SModeInfo * pkD3DModeInfo = pkD3DAdapterInfo->GetD3DModeInfop(ms_iD3DDevInfo, ms_iD3DModeInfo);     
    if (!pkD3DModeInfo)
    {
        Tracenf("device %d, mode %d is EMPTY", ms_iD3DDevInfo, ms_iD3DModeInfo);
        return CREATE_DETECT;
    }

    D3DADAPTER_IDENTIFIER9& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier();
    if (Windowed &&
        strnicmp(rkD3DAdapterId.Driver, "3dfx", 4)==0 &&
        22 == pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format)
    {
        return CREATE_FORMAT;
    }

    if (pkD3DModeInfo->m_dwD3DBehavior==D3DCREATE_SOFTWARE_VERTEXPROCESSING)
    {
        iRet |= CREATE_NO_TNL;

        // DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
        //__WarningMessage(hWnd, CREATE_NO_TNL);
        // END_OF_DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
    }

    std::string stModeInfo;
    pkD3DModeInfo->GetString(&stModeInfo);

    //Tracen(stModeInfo.c_str());

    int ErrorCorrection = 0;

RETRY:
    ZeroMemory(&ms_d3dPresentParameter, sizeof(ms_d3dPresentParameter));
    
    ms_d3dPresentParameter.Windowed                         = Windowed;
    ms_d3dPresentParameter.BackBufferWidth                  = iHres;
    ms_d3dPresentParameter.BackBufferHeight                 = iVres;
    ms_d3dPresentParameter.hDeviceWindow                    = hWnd;
    ms_d3dPresentParameter.BackBufferCount                  = m_uBackBufferCount;
    ms_d3dPresentParameter.SwapEffect                       = D3DSWAPEFFECT_DISCARD;

    if (Windowed)
    {
        ms_d3dPresentParameter.BackBufferFormat             = pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format;
    }
    else
    {
        ms_d3dPresentParameter.BackBufferFormat             = pkD3DModeInfo->m_eD3DFmtPixel;
        ms_d3dPresentParameter.FullScreen_RefreshRateInHz   = iReflashRate;
    }

    ms_d3dPresentParameter.Flags                            = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    ms_d3dPresentParameter.EnableAutoDepthStencil           = TRUE;
    ms_d3dPresentParameter.AutoDepthStencilFormat           = pkD3DModeInfo->m_eD3DFmtDepthStencil;

    ms_dwD3DBehavior = pkD3DModeInfo->m_dwD3DBehavior;

    if (FAILED(ms_hLastResult = ms_lpd3d->CreateDevice(
                ms_iD3DAdapterInfo,
                D3DDEVTYPE_HAL,
                hWnd,
                pkD3DModeInfo->m_dwD3DBehavior,
                &ms_d3dPresentParameter,
                &ms_lpd3dDevice)))
    {
        switch (ms_hLastResult)
        {
            case D3DERR_INVALIDCALL:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_INVALIDCALL\nThe method call is invalid. For example, a method's parameter may have an invalid value.");                    
                break;
            case D3DERR_NOTAVAILABLE:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_NOTAVAILABLE\nThis device does not support the queried technique. ");
                break;
            case D3DERR_OUTOFVIDEOMEMORY:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_OUTOFVIDEOMEMORY\nDirect3D does not have enough display memory to perform the operation");
                break;
            default:
                Tracenf("IDirect3DDevice.CreateDevice - ERROR %d", ms_hLastResult);
                break;
        }

        if (ErrorCorrection)
            return CREATE_DEVICE;
    
        iReflashRate = 0;
        ++ErrorCorrection;
        iRet = CREATE_REFRESHRATE;
        goto RETRY;
    }

    // Check DXT Support Info
    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo, 
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT1) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo, 
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT3) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }

    if(ms_lpd3d->CheckDeviceFormat(
                ms_iD3DAdapterInfo, 
                D3DDEVTYPE_HAL,
                ms_d3dPresentParameter.BackBufferFormat,
                0,
                D3DRTYPE_TEXTURE,
                D3DFMT_DXT5) == D3DERR_NOTAVAILABLE)
    {
        ms_bSupportDXT = false;
    }   

    if (FAILED((ms_hLastResult = ms_lpd3dDevice->GetDeviceCaps(&ms_d3dCaps))))
    {
        Tracenf("IDirect3DDevice.GetDeviceCaps - ERROR %d", ms_hLastResult);
        return CREATE_GET_DEVICE_CAPS2;
    }

    if (!Windowed)
        SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, iHres, iVres, SWP_SHOWWINDOW);

    //Tracef("vertex shader version : %X\n",(DWORD)ms_d3dCaps.VertexShaderVersion);

    ms_lpd3dDevice->GetViewport(&ms_Viewport);

    m_pStateManager = new CStateManager(ms_lpd3dDevice);

    D3DXCreateMatrixStack(0, &ms_lpd3dMatStack);
    ms_lpd3dMatStack->LoadIdentity();

    ms_ptVS = CreatePTStreamVertexShader();
    ms_pntVS = CreatePNTStreamVertexShader();
    ms_pnt2VS = CreatePNT2StreamVertexShader();

    D3DXMatrixIdentity(&ms_matIdentity);
    D3DXMatrixIdentity(&ms_matView);
    D3DXMatrixIdentity(&ms_matProj);
    D3DXMatrixIdentity(&ms_matInverseView);
    D3DXMatrixIdentity(&ms_matInverseViewYAxis);
    D3DXMatrixIdentity(&ms_matScreen0);
    D3DXMatrixIdentity(&ms_matScreen1);
    D3DXMatrixIdentity(&ms_matScreen2);

    ms_matScreen0._11 = 1;
    ms_matScreen0._22 = -1; 

    ms_matScreen1._41 = 1;
    ms_matScreen1._42 = 1;

    ms_matScreen2._11 = (float) iHres / 2;
    ms_matScreen2._22 = (float) iVres / 2;
    
    D3DXCreateSphere(ms_lpd3dDevice, 1.0f, 32, 32, &ms_lpSphereMesh, NULL);
    D3DXCreateCylinder(ms_lpd3dDevice, 1.0f, 1.0f, 1.0f, 8, 8, &ms_lpCylinderMesh, NULL);

    ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);

    if (!__CreateDefaultIndexBufferList())
        return false;

    if (!__CreatePDTVertexBufferList())
        return false;
    
    DWORD dwTexMemSize = GetAvailableTextureMemory();

    if (dwTexMemSize < 64 * 1024 * 1024)
        ms_isLowTextureMemory = true;
    else
        ms_isLowTextureMemory = false;

    if (dwTexMemSize > 100 * 1024 * 1024)
        ms_isHighTextureMemory = true;
    else
        ms_isHighTextureMemory = false;

    if (ms_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=false;
    else
        GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=true;

    //D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier();
    if (strnicmp(rkD3DAdapterId.Driver, "SIS", 3) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = true;
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }
    else if (strnicmp(rkD3DAdapterId.Driver, "3dfx", 4) == 0)
    {
        GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
        GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
        ms_isLowTextureMemory = true;
    }

    return (iRet);
}

This code works without errors. There is no problem. However:

ms_d3dPresentParameter.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
ms_d3dPresentParameter.MultiSampleQuality = 0;

Although it compiles without any problems when I add this, the exe does not open and gives the error "Sorry, your system does not support 3D Graphic....".

I looked in debug and the following part is triggered:

case D3DERR_INVALIDCALL:
                Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_INVALIDCALL\nThe method call is invalid. For example, a method's parameter may have an invalid value.");                    
                break;

I use Windows 10 64bit and 4060Ti Graphic Card. Updated all drivers.

Advertisement

https://learn.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3d9-createdevice

Back buffers created as part of the device are only lockable if D3DPRESENTFLAG_LOCKABLE_BACKBUFFER is specified in the presentation parameters. (Multisampled back buffers and depth surfaces are never lockable.)

@Juliean Firstly, thank you.

However, I must clearly state that I am a novice in directx programming. What does this mean and what should I do?

cvaqabond said:
However, I must clearly state that I am a novice in directx programming. What does this mean and what should I do?

It means that you cannot both use multi-sampling and a lockable backbuffer at the same time. You need to determine what the application is locking the backbuffer for, and if it could potentially be avoided. If not, you canno thave multisampling on the backbuffer per-se, and you need some other form of multipsamping (ie. different post-process based approaches, or by specifying multisampling on an offscreen-render target that is later copied into the backbuffer).

This topic is closed to new replies.

Advertisement