Saturday, September 17, 2022
HomeGame Developmentdirectx - Texture doesn't draw with ATI Radeon RX, however does with...

directx – Texture doesn’t draw with ATI Radeon RX, however does with NVIDIA/no GPU


I get an issue when making an attempt to attract a texture on the next {hardware} (configuration 1):

ATi Radeon RX 6600 XT

Display (OS Home windows 11):
Window with green background, no texture displayed

I’ve different {hardware} (configuration 2):

nVidia Geforce GTX950M

And it has no issues. Display (OS Home windows 10):
Image of the Earth on a green background

My code (I made a minimal instance):

#embrace <Home windows.h>

#embrace "Useful resource.h"

#embrace <d3d9.h>
#embrace <d3dx9math.h>
#embrace <dxerr9.h>

#embrace "stb_image.h"
#embrace <cassert>
#embrace <fstream>
#embrace <vector>

typedef intptr_t HTEXTURE;

struct vertex
{
    vertex() {}
    vertex(float x, float y, float z, DWORD col, float tx, float ty, float tx2, float ty2) :x(x), y(y), z(z), col(col), tx(tx), ty(ty),
        tx2(tx2), ty2(ty2) {}
    float           x, y;   
    float           z;          
    DWORD           col;        
    float           tx, ty;     
    float           tx2, ty2;
};

struct Quad
{
    vertex      v[4];
    HTEXTURE        tex;
    int             mix;
};


#outline D3DFVF_HGEVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEX2)          
#outline D3DFVF_HGE_MASKEDVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEX2)   
#outline VERTEX_BUFFER_SIZE 4000
#outline BLEND_COLORMUL      0
#outline BLEND_ALPHABLEND    2
#outline BLEND_NOZWRITE      0
#outline BLEND_DEFAULT       (BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE)

HINSTANCE hInst;
WCHAR szTitle[] = L"take a look at";
WCHAR szWindowClass[] = L"test_win";
HWND hWnd;
IDirect3D9* pD3D;
IDirect3DDevice9* pD3DDevice;
D3DPRESENT_PARAMETERS* d3dpp;
D3DPRESENT_PARAMETERS                       d3dppW;
D3DPRESENT_PARAMETERS                       d3dppFS;
int                                         nScreenBPP;
D3DXMATRIX                                  matProj;
D3DXMATRIX                                  matView;
vertex* VertArray;
IDirect3DVertexBuffer9* pVB;
IDirect3DIndexBuffer9* pIB;
int                                         nPrim = 0;
D3DVIEWPORT9                                rCurrentViewPort;
RECT                    rectW;
LONG                    styleW;
Quad quad;
IDirect3DTexture9* pD3DXTex = 0;

BOOL                InitWin(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);


int _format_id(D3DFORMAT fmt)
{
    swap (fmt)
    {
    case D3DFMT_R5G6B5:     return 1;
    case D3DFMT_X1R5G5B5:   return 2;
    case D3DFMT_A1R5G5B5:   return 3;
    case D3DFMT_X8R8G8B8:   return 4;
    case D3DFMT_A8R8G8B8:   return 5;
    default:                return 0;
    }
}

void _SetProjectionMatrix(int width, int top)
{
    D3DXMATRIX tmp;
    D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f);
    D3DXMatrixTranslation(&tmp, -0.5f, top + 0.5f, 0.0f);
    D3DXMatrixMultiply(&matProj, &matProj, &tmp);
    D3DXMatrixOrthoOffCenterLH(&tmp, 0.f, (float)width, 0, (float)top, 0.0f, 1.0f);
    D3DXMatrixMultiply(&matProj, &matProj, &tmp);
}

bool initD3d()
{
    static const char* szFormats[] = { "UNKNOWN", "R5G6B5", "X1R5G5B5", "A1R5G5B5", "X8R8G8B8", "A8R8G8B8" };
    D3DDISPLAYMODE          Mode;
    D3DFORMAT               Format = D3DFMT_UNKNOWN;
    UINT nModes, i;

    pD3D = Direct3DCreate9(D3D_SDK_VERSION); 

    pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode);

    ZeroMemory(&d3dppW, sizeof(d3dppW));

    d3dppW.BackBufferWidth = 1366;
    d3dppW.BackBufferHeight = 768;
    d3dppW.BackBufferFormat = Mode.Format;
    d3dppW.BackBufferCount = 1;
    d3dppW.MultiSampleType = D3DMULTISAMPLE_NONE;
    d3dppW.hDeviceWindow = hWnd;
    d3dppW.Windowed = TRUE;

    d3dppW.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dppW.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

    nModes = pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, Mode.Format);

    int nFullscreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int nFullscreenHeight = GetSystemMetrics(SM_CYSCREEN);

    for (i = 0; i < nModes; ++i)
    

    if (Format == D3DFMT_UNKNOWN)
    {
        return false;
    }

    ZeroMemory(&d3dppFS, sizeof(d3dppFS));

    d3dppFS.BackBufferWidth = 1366;
    d3dppFS.BackBufferHeight = 768;
    d3dppFS.BackBufferFormat = Mode.Format;
    d3dppFS.BackBufferCount = 1;
    d3dppFS.MultiSampleType = D3DMULTISAMPLE_NONE;
    d3dppFS.hDeviceWindow = hWnd;
    d3dppFS.Windowed = TRUE;
    d3dppFS.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dppFS.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

    d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

    d3dpp = true ? &d3dppW : &d3dppFS;

    if (_format_id(d3dpp->BackBufferFormat) < 4)
        nScreenBPP = 16;
    else
        nScreenBPP = 32;

    // Create D3D Gadget
    UINT       nAdapter = D3DADAPTER_DEFAULT;
    D3DDEVTYPE eDeviceType = D3DDEVTYPE_HAL;

    D3DCAPS9 caps;
    pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);

    DWORD dwVP;
    if ((caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) || !(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT))
     D3DCREATE_MULTITHREADED;
    
    else
     D3DCREATE_MULTITHREADED;
    

    dwVP = D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED;

    pD3D->CreateDevice(nAdapter, eDeviceType, hWnd, dwVP, d3dpp, &pD3DDevice);

    _SetProjectionMatrix(1366, 768);
    D3DXMatrixIdentity(&matView);

    return true;
}

IDirect3DTexture9* loadTexture(IDirect3DTexture9* texture, const std::string& path)
 std::ios::ate);
    dwSizeFile = file.tellg();
    file.seekg(0, std::ios::beg);
    std::vector<char> pDataTex(dwSizeFile);
    if (!file.learn(pDataTex.information(), dwSizeFile))
        return nullptr;

    fmt1 = D3DFMT_A8R8G8B8;
    fmt2 = D3DFMT_UNKNOWN;

    int nWidth, nHeight, nBPP;
    int nRet = stbi_info_from_memory((stbi_uc*)pDataTex.information(), dwSizeFile, &nWidth, &nHeight, &nBPP);

    HRESULT hr = D3DXCreateTextureFromFileInMemoryEx(pD3DDevice, pDataTex.information(), dwSizeFile,
        D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2,
        0,  // Mip ranges
        0,                              // Utilization
        fmt1,                           // Format
        D3DPOOL_MANAGED,                // Reminiscence pool
        D3DX_FILTER_NONE,               // Filter
        D3DX_DEFAULT,                   // Mip filter
        0,                              // Colour key
        NULL, NULL, &texture);

    return texture;


bool initQuad()
{
    quad.v[0] = vertex(0, 0, 1, -1, 0, 0, 0, 0);
    quad.v[1] = vertex(1100, 0, 1, -1, 1, 0, 0, 0);
    quad.v[2] = vertex(1100, 650, 1, -1, 1, 1, 0, 0);
    quad.v[3] = vertex(0, 650, 1, -1, 0, 1, 0, 0);
    quad.tex = -1;
    quad.mix = 2;

    return true;
}

bool initGeometry()
{
    VertArray = 0;

    pD3DDevice->CreateVertexBuffer(VERTEX_BUFFER_SIZE * sizeof(vertex), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_HGEVERTEX, D3DPOOL_DEFAULT, &pVB, NULL);

    pD3DDevice->SetVertexShader(NULL);
    pD3DDevice->SetFVF(D3DFVF_HGEVERTEX);
    pD3DDevice->SetStreamSource(0, pVB, 0, sizeof(vertex));

    pD3DDevice->CreateIndexBuffer(VERTEX_BUFFER_SIZE * 6 / 4 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &pIB, NULL);

    WORD* pIndices, n = 0;
    if (FAILED(pIB->Lock(0, 0, (void**)&pIndices, 0)))
    {
        return false;
    }

    for (int i = 0; i < VERTEX_BUFFER_SIZE / 4; i++)
    {
        *pIndices++ = n;
        *pIndices++ = n + 1;
        *pIndices++ = n + 2;
        *pIndices++ = n + 2;
        *pIndices++ = n + 3;
        *pIndices++ = n;
        n += 4;
    }

    pIB->Unlock();
    pD3DDevice->SetIndices(pIB);

    pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

    pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    pD3DDevice->SetRenderState(D3DRS_ALPHAREF, 0x01);
    pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);

    pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
    pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

    pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
    pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); // TODO: drawback
    pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    pD3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);

    pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

    pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

    pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
    pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
    pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);

    pD3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
    pD3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
    pD3DDevice->SetSamplerState(1, D3DSAMP_BORDERCOLOR, D3DCOLOR_ARGB(0x0, 0, 0, 0));

    pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
    pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);

    D3DVIEWPORT9 vp;
    HRESULT hr = pD3DDevice->GetViewport(&vp);
    if (hr == D3D_OK)
        rCurrentViewPort = vp;

    pD3DXTex = loadTexture(pD3DXTex, "Tiger-PNG-Picture.png");
    initQuad();

    return true;
}

void SetTexture()
{
    pD3DDevice->SetTexture(0, pD3DXTex);
}

bool beginScene()
{
    pD3DDevice->BeginScene();
    pVB->Lock(0, 0, (VOID**)&VertArray, D3DLOCK_DISCARD);
    return true;
}

void endScene()
{
    pVB->Unlock();
    VertArray = 0;
    nPrim = 0;
    pD3DDevice->EndScene();

    pD3DDevice->Current(NULL, NULL, NULL, NULL);
}

void clearScene()
{
    int coloration = D3DCOLOR_ARGB(255, 0, 125, 0);
    pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, coloration, 1.0f, 0);
}

void renderQuad(Quad* quad)
{
    SetTexture();
    memcpy(&VertArray[nPrim * 4], quad->v, sizeof(vertex) * 4);
    nPrim++;
    pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, nPrim << 2, 0, nPrim << 1);
}

void _UpdateRects()
 WS_VISIBLE;
    AdjustWindowRect(&rectW, styleW, FALSE);



BOOL InitWin(HINSTANCE hInstance, int nCmdShow)
 CS_HREDRAW 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    swap (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)
{
    if (!InitWin(hInstance, nCmdShow))
        return FALSE;


    MSG msg = { 0 };

    initD3d();
    initGeometry();

    whereas (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            if (GetMessage(&msg, NULL, 0, 0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else
        {
            clearScene();
            beginScene();
            renderQuad(&quad);
            endScene();
        }
    }

    return (int)msg.wParam;
}

The issue is on this line:

pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); // TODO: drawback

Additionally, if I set one other texture for rendering at index 1, then all the things will work (not accurately, however the rendering will work):

pD3DDevice->SetTexture(0, pD3DXTex);
pD3DDevice->SetTexture(1, pD3DXTex); // this

How you can repair it?

P.S.: I examined on a Home windows 11 digital machine with configuration 1, however and not using a video card – all the things labored accurately.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments