0
\$\begingroup\$

I'm trying to write a wrapper for the CreateShaderResourceView method inside my Texture class, which shouldn't be any problem at all since everything was working fine outside the class. But the debug layer reports an error when assertion is called at the creation of the pipeline state:

D3D12 ERROR: ID3D12Device::CreateShaderResourceView: The PlaneSlice -858993460 is invalid when the resource format is B8G8R8A8_UNORM and the view format is B8G8R8A8_UNORM.  Only Plane Slice 0 is valid when creating a view on a non-planar format. [ STATE_CREATION ERROR #344: CREATEUNORDEREDACCESSVIEW_INVALIDPLANESLICE]
D3D12 ERROR: ID3D12Device::CreateShaderResourceView: The Dimensions of the View are invalid due to at least one of the following conditions. MostDetailedMip (value = -858993460) must be between 0 and MipLevels-1 of the Texture Resource, 0, inclusively. With the current MostDetailedMip, MipLevels (value = 1) must be between 1 and 0, inclusively, or -1 to default to all mips from MostDetailedMip, in order that the View fit on the Texture. [ STATE_CREATION ERROR #31: CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS]
D3D12: Removing Device.

The wrapper function is simple and operates on a map:

void Texture::CreateSRVFromTexture(const Textures::ID & id, CD3DX12_CPU_DESCRIPTOR_HANDLE & cpuHandle)
{
    auto found = m_textures.find(id);

    //Create SRV with the CPU handle
    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
    srvDesc.Format = found->second.textureDesc.Format;
    srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
    srvDesc.Texture2D.MipLevels = 1;
    m_device->CreateShaderResourceView(found->second.textureBuffer, &srvDesc, cpuHandle);
}

And calling this function looks like this:

CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle1(m_textureDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), 0,
        m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV));
m_texture->CreateSRVFromTexture(Textures::ID::Fatboy, srvHandle1);

Now I don't understand why it worked perfectly fine before (no errors reported) when I didn't have the wrapper method and simply accessed the texture with a Get method. What could be the cause of this, since the error message is a bit vague and doesn't help very much?

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

D3D12_SHADER_RESOURCE_VIEW_DESC is a structure; it has no constructors to default-initialize any fields.

Thus, when you create an instance of one on the stack, the values of all fields are essentially randomly garbage. You then proceed to assign values to some of the fields. However, you don't assign values to all of them. You leave several of the members of the nested Texture2D member alone, including PlaneSlice and MostDetailedMip, which are two that the API is complaining about.

You should initialize all fields of the structure, either explicitly or at least (when valid) using something like D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {0};

\$\endgroup\$
  • \$\begingroup\$ Silly, but this is indeed the solution to the problem. Thanks for the quick response! \$\endgroup\$ – Riggs Feb 9 '18 at 21:33
  • 1
    \$\begingroup\$ Note that ere are some C++ helpers in the D3DX12.H utility header that have C++ constructors for common structs. \$\endgroup\$ – Chuck Walbourn Feb 10 '18 at 2:08
  • 1
    \$\begingroup\$ Also note that with VS 2013 or later which implements C++11 uniform initialization, you actually can zero-fill a structure by using: D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; \$\endgroup\$ – Chuck Walbourn Feb 15 '18 at 16:52

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.