0
\$\begingroup\$

i am implementing Mipmapping for my texture for the first time.

i have 2 questions

  1. HOW TO CHECK IF MIPMAP IS DONE PROPERLY ?
  2. HOW TO SET MIPMAP FOR TEXTURE FROM FILE ?

First one. i implemented texture in application.

ID3D11Texture2D* TEX;
D3D11_TEXTURE2D_DESC DESC;
DESC.ArraySize = 1;
DESC.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
DESC.CPUAccessFlags = 0;
DESC.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
DESC.Width = 256;
DESC.Height = 256;
DESC.MipLevels = 9;
DESC.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
DESC.SampleDesc.Count = 1;
DESC.SampleDesc.Quality = 0;
DESC.Usage = D3D11_USAGE_DEFAULT;
r_assert(graphic->Device()->CreateTexture2D(&DESC, nullptr, &TEX));
ID3D11ShaderResourceView* TEXV;
D3D11_SHADER_RESOURCE_VIEW_DESC TEXVDESC;
TEXVDESC.Format = DESC.Format;
TEXVDESC.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
TEXVDESC.Texture2D.MipLevels = -1;
TEXVDESC.Texture2D.MostDetailedMip = 0;
r_assert(graphic->Device()->CreateShaderResourceView(TEX, &TEXVDESC, &TEXV));
graphic->DContext()->GenerateMips(TEXV);
D3D11_TEXTURE2D_DESC desc;
TEX->GetDesc(&desc);

not sure, but i think i generate Mipmap for TEX and i just want to know the ways how to check/debug if mipmap actually done well.


Second. i am also using DirectX::CreateWICTextureFromFileEx to create texture from file.

resource=nullptr;
newSRV=nullptr;

r_assert(
    DirectX::CreateWICTextureFromFileEx(
        graphic->Device(),
        (L"Data\\Texture\\" + fileName).c_str(),
        0,
        D3D11_USAGE_DEFAULT,
        D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
        0,
        D3D11_RESOURCE_MISC_GENERATE_MIPS,
        DirectX::WIC_LOADER_DEFAULT,
        &resource,
        &newSRV)
);
graphic->DContext()->GenerateMips(newSRV);
ID3D11Texture2D* tex = nullptr;
r_assert(
    resource->QueryInterface(IID_ID3D11Texture2D, (void**)&tex)
);
D3D11_TEXTURE2D_DESC desc;
tex->GetDesc(&desc);

and i checked desc.MipLevels is 1, which means there is no mipmapping. so wonder how to generate mipmap when using WIC function?

any advice would be appreciated^

\$\endgroup\$
1
\$\begingroup\$

One way is capturing a frame with a graphics debugger, such as RenderDoc, Nsight, Visual Studio graphics debugger or something else, search for your texture in the resources window (different names with different programs of course), and see if there are any mip levels. You can also view any specific mip level.

An other way is to sample the texture in a shader with SampleLevel(), where you provide the mip level as the last argument to the funcion, and output the texture to the screen, so you will see if there are any mips. If there is only one mip level set for the texture, it will always return mip0. If there are multiple mip levels, but you didn't generate mip levels, then mips greater than zero will return black. If everything is correct, mips greater than zero will return a lower resoution texture.

Also, if you enable the debug layer and call GenerateMips(), and there are no error messages, it's safe bet that mip levels are generated fine.

Second question: I only used CreatWICTexture function a long time ago, but I remember that you could provide the device context as one of the arguments, and then it would generate mip levels. (but the interface might have changed by then)

Good luck!

\$\endgroup\$
  • \$\begingroup\$ Hi janos!! thanks for reply. i tried to test using texture function in shader. and since there is no initial value for texture, every miplevel seems black. so wonder if you know any way to initialize value into that mipmap texture?(i can't set subresource_data for mipmap texture). And in case of wic function, what kind function do you use for creating texture from filepath??? \$\endgroup\$ – KIM CHANGJUN Sep 1 at 1:37
  • 1
    \$\begingroup\$ Every mip level is black, even the first one? Then initialize the first one via subresource data when you create the texture, or render something into it. GenerateMips() only makes sense if the first mip already contains something. CreateWicTexture also fills the first mip, then calls GenerateMips() if the device context argument is provided. \$\endgroup\$ – János Turánszki Sep 1 at 11:59
  • \$\begingroup\$ Thanks janos!! i use `updatesubresource' function and success to initialize mipmap texture!!. and the mipmapping seems working because it(texture) is getting dark as i move camera away from object. i will try mipmapping CreateWicTexture later. thansk for reply it was very helpful^^ \$\endgroup\$ – KIM CHANGJUN Sep 2 at 0:17
1
\$\begingroup\$

My solution.

So my approach is

  1. i prepare image that i want to render with mipmap effect in file
  2. create resource of that image(i used CreateWICTextureFromFile)
  3. create an empty texture with mipmap setting.
  4. read data from image and store in cpu
  5. copy that data into texture with mipmapsetting
  6. DeviceContext->GenerateMaps
ID3D11Texture2D* image = TextureMgr::Instance()->GetTexture("grass.jpg"); // it is just my custom function that read texture from file and return resource of it.

ID3D11Texture2D* tex = nullptr; // FIRST generate mipmap texture________________________________
D3D11_TEXTURE2D_DESC texDesc;
image->GetDesc(&texDesc);
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
texDesc.CPUAccessFlags = 0;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.MipLevels = 7;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
texDesc.Usage = D3D11_USAGE_DEFAULT;
r_assert(device->CreateTexture2D(&texDesc, nullptr, &tex));

ID3D11Texture2D* stagTex; // create Staging texture_____________________________________
D3D11_TEXTURE2D_DESC stagDesc;
image->GetDesc(&stagDesc);
stagDesc.ArraySize = 1;
stagDesc.BindFlags = 0;
stagDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
stagDesc.MipLevels = 1;
stagDesc.MiscFlags = 0;
stagDesc.Usage = D3D11_USAGE_STAGING;
r_assert(device->CreateTexture2D(&stagDesc, nullptr, &stagTex));

// read from image_________________________________________________________________________
graphic->DContext()->CopyResource(stagTex, image); 
D3D11_MAPPED_SUBRESOURCE mapped;
r_assert(graphic->DContext()->Map(stagTex, 0, D3D11_MAP_READ, 0, &mapped));
UINT* arr = new UINT[(mapped.RowPitch/(float)sizeof(UINT)) * stagDesc.Height];
ZeroMemory(arr, mapped.RowPitch*stagDesc.Height);
CopyMemory(arr, mapped.pData, mapped.RowPitch*stagDesc.Height);
graphic->DContext()->Unmap(stagTex, 0);

// copy image data into mipmap texture_______________________________________________________________
graphic->DContext()->UpdateSubresource(tex, 0, &CD3D11_BOX(0, 0, 0, stagDesc.Width, stagDesc.Height, 1), arr, mapped.RowPitch, mapped.DepthPitch); 

// create SRV of mipmap texture______________________________________________________________
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = texDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = texDesc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
r_assert(device->CreateShaderResourceView(tex, &srvDesc, &srv));
graphic->DContext()->GenerateMips(srv);

now you can use this final srv with mipmap setting.

Good luck

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.