• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
hupsilardee

DX11
Mip map initialisation

3 posts in this topic

So my adventures in D3D11 continue. I am struggling to understand how mipmapping works. In this project I am also trying not to depend on D3DX11 so I am creating textures programmatically. However I am struggling to understand how the mip map generation works. Here's how I create a texture (minus error checking etc)

[code]

DWORD* loaded_data; // loaded using FreeImage

uint width = FreeImage_GetWidth(image32);
uint height = FreeImage_GetHeight(image32);
uint mips = GetNumMipLevels(width, height);
Desc.Width = width;
Desc.Height = height;
Desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
Desc.MipLevels = mips; // auto-generates the whole chain
Desc.MiscFlags = 0;
Desc.ArraySize = 1;
Desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
Desc.CPUAccessFlags = 0;
Desc.SampleDesc.Count = 1;
Desc.SampleDesc.Quality = 0;
Desc.Usage = D3D11_USAGE_IMMUTABLE;

D3D11_SUBRESOURCE_DATA* initialData = new D3D11_SUBRESOURCE_DATA[mips];

for (uint i = 0; i < mips; i++)
{
uint mip = (uint)powf(2.f, (float)i);
initialData[i].pSysMem = loaded_data;
initialData[i].SysMemPitch = width * 4;
initialData[i].SysMemSlicePitch = width * height * 4;
}

pDevice->pDevice->CreateTexture2D(&Desc, initialData, &pTexture);
delete[] initialData;

D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
ZeroMemory(&viewDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
viewDesc.Format = Desc.Format;
viewDesc.Texture2D.MipLevels = -1;
viewDesc.Texture2D.MostDetailedMip = 0;
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;

pDevice->pDevice->CreateShaderResourceView(pTexture, &viewDesc, &pView);

return S_OK;

[/code]

However I don't think this is generating the mip maps correctly, or they aren't being used. Look at the left of the cube in this screenshot

[url="http://imageshack.us/photo/my-images/209/32138660.png/"][img]http://img209.imageshack.us/img209/6316/32138660.png[/img][/url]
Uploaded with [url="http://imageshack.us"]ImageShack.us[/url]

I dont [i]think[/i] the sampler is at fault, but just in case, it is set up like this
[code]
D3D11_SAMPLER_DESC desc;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = desc.AddressU;
desc.AddressW = desc.AddressU;
desc.BorderColor[0] = desc.BorderColor[1] = desc.BorderColor[2] = desc.BorderColor[3] = 1.0f;
desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.MaxAnisotropy = 0;
desc.MaxLOD = 0;
desc.MinLOD = 0;
desc.MipLODBias = 0.0f;
[/code]

So can anyone see what I'm doing wrong?
0

Share this post


Link to post
Share on other sites
The way you're trying to do things would require that you have the mipmap data already generated when you created the function. There is no "automatic" mip generation for IMMUTABLE textures, since they require that you pass [i]all[/i] of the required data to it. What you're actually doing in your code is you're passing the top-level mip data to all of the lower-resolution mip levels, which isn't right. If you do have all of the mips generated, then for each D3D11_SUBRESOURCE_DATA you need to have it point to the data for that mip. You would also need to set the proper pitch for that mip level, which get smaller as you go up in the levels.

If you don't actually have the mips generated and you want them to be generated by the hardware, you need to set it up differently. Here's an example of how to do it, taken from the WICTextureLoader sampler from DirectXTex:

[code]
// Create texture
D3D11_TEXTURE2D_DESC desc;
desc.Width = twidth;
desc.Height = theight;
desc.MipLevels = (autogen) ? 0 : 1;
desc.ArraySize = 1;
desc.Format = format;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = (autogen) ? (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) : (D3D11_BIND_SHADER_RESOURCE);
desc.CPUAccessFlags = 0;
desc.MiscFlags = (autogen) ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = temp.get();
initData.SysMemPitch = static_cast<UINT>( rowPitch );
initData.SysMemSlicePitch = static_cast<UINT>( imageSize );
ID3D11Texture2D* tex = nullptr;
hr = d3dDevice->CreateTexture2D( &desc, (autogen) ? nullptr : &initData, &tex );
if ( SUCCEEDED(hr) && tex != 0 )
{
if (textureView != 0)
{
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
memset( &SRVDesc, 0, sizeof( SRVDesc ) );
SRVDesc.Format = format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1;
hr = d3dDevice->CreateShaderResourceView( tex, &SRVDesc, textureView );
if ( FAILED(hr) )
{
tex->Release();
return hr;
}
if ( autogen )
{
assert( d3dContext != 0 );
d3dContext->UpdateSubresource( tex, 0, nullptr, temp.get(), static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize) );
d3dContext->GenerateMips( *textureView );
}
}
}
[/code]
1

Share this post


Link to post
Share on other sites
Sorry to bump such an old thread. I would like to say, thanks for the help MJP, and it has been solved as you said. FreeImage has image resize functions which made it very quick and easy, and they support a variety of filters as well, which is great.

I have another question about this method though. It appears that you are marking it for default usage and as a potential render target.
Surely there is a performance hit for this?

(I thought that if the texture is IMMUTABLE on some cards it goes in a different texture memory that the hardware can access faster. However if not then this is doubly excellent, not only is texture generation likely to be much faster due to GPU mip map generation, but all textures can be render targets, so I could have super fast bullet holes and decals!)

I am also bumping to point out that the sampler is in fact incorrectly set up. As the MinLOD and MaxLOD members are both set to 0, this forces the sampler to use only the most detailed mip, which of course is wrong. The correct sampler state is as above, with:

[code]
desc.MaxLOD = D3D11_FLOAT32_MAX; // or simply FLT_MAX
desc.MinLOD = 0;
[/code]
0

Share this post


Link to post
Share on other sites
It's possible that using default usage and render target binding could cause different behavior for a texture, but that's completely dependent on the hardware and the driver. Your best bet for GPU performance is to use IMMUTABLE, since that guaranteed that the driver will put the texture in the best possible memory location with the best possible memory layout for that use case.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • By lonewolff
      Hi Guys,
      I am just wondering if it is possible to acquire the address of the backbuffer if an API (based on DX11) only exposes the 'device' and 'context' pointers?
      Any advice would be greatly appreciated
    • By MarcusAseth
      bool InitDirect3D::Init() { if (!D3DApp::Init()) { return false; } //Additional Initialization //Disable Alt+Enter Fullscreen Toggle shortkey IDXGIFactory* factory; CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&factory)); factory->MakeWindowAssociation(mhWindow, DXGI_MWA_NO_WINDOW_CHANGES); factory->Release(); return true; }  
      As stated on the title and displayed on the code above, regardless of it Alt+Enter still takes effect...
      I recall something from the book during the swapChain creation, where in order to create it one has to use the same factory used to create the ID3D11Device, therefore I tested and indeed using that same factory indeed it work.
      How is that one particular factory related to my window and how come the MakeWindowAssociation won't take effect with a newly created factory?
      Also what's even the point of being able to create this Factories if they won't work,?(except from that one associated with the ID3D11Device) 
    • By ProfL
      Can anyone recommend a wrapper for Direct3D 11 that is similarly simple to use as SFML? I don't need all the image formats etc. BUT I want a simple way to open a window, allocate a texture, buffer, shader.
    • By lucky6969b
      Q1:
      Since there is no more fixed pipeline rendering in DX11, for every part of rendering in DX11, do I need to create a brand-new vertex shader and pixel shader... or at least I have to find one relevant online. If you work on skinned meshes and other effects originally worked in DX9 fixed pipeline, do I have to rework everything by now?
       
      Q2:
      For assimp, if it originally was designed for DX9, like it is coupled to a DX9 device for creating meshes and materials etc. Do I have to add in the DX11 device in the assimp, or can I just leave the assimp to remain in DX9 and after the meshes are loaded, I just convert the vertex buffers and index buffers into DX11 buffers?
      Thanks
      Jack
    • By MarcusAseth
      This header is mentioned in the book I'm reading but there is no documentation on msdn... Is it like an... outdated and abandoned header?
      If so, what's the current default/recomended library for handling errors with directX?
  • Popular Now