locked
DrawInstanced/DrawIndexedInstanced Bug on Windows Phone 8.1

    Question

  • Hi,

    I have a Nokia Lumia 930 with OS version 8.10.14226.359.

    Whenever I try to invoke ID3D11DeviceContext::DrawInstanced in a Windows Store App. it responds with device removal:

    D3D11: Removing Device. 
    D3D11 WARNING: ID3D11Device::RemoveDevice: Device removal has been triggered for the following reason (DXGI_ERROR_DRIVER_INTERNAL_ERROR: There is strong evidence that the driver has performed an undefined operation; but it may be because the application performed an illegal or undefined operation to begin with.). [ EXECUTION WARNING #379: DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT] 

    If build the same app to desktop it works as expected.

    Then, I investigated further, and modified the DirectX Sample Windows Store App. to use instanced data.

    It seems the ID3D11DeviceContext::DrawIndexedInstanced method ignores the StartInstanceLocation parameter on Windows Phone. So I cannot draw more than 256 instances in one frame with multiple DrawIndexedInstanced calls.

    When I build it as a desktop app it works as expected.

    Anyone experienced similar issues?

    Thanks,

    Andras


    Saturday, February 21, 2015 1:48 PM

All replies

  • You should post the code in here.

    Vote if help you

    Monday, February 23, 2015 5:39 AM
  •  I had no better idea, so I modified the example DirectX App in the store apps, and paste it here the modifications:

    in Sample3DSceneRenderer::CreateDeviceDependentResources() i replaced the vertexDesc:

    static const D3D11_INPUT_ELEMENT_DESC vertexDesc [] =
    		{
    			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    			{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    			{ "POSITION", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
    		};

    at the end of createCubeTask, I added:

    static DirectX::XMFLOAT3 instanceData[512];
    		//float x = -4.f, y = -4.f, z = -4.f;
    		for (int i = 0; i < 512; i++) {
    			instanceData[i].x = -4.f + 1.f * (i % 8);
    			instanceData[i].y = -4.f + 1.f * ((i / 8) % 8);
    			instanceData[i].z = -4.f + 1.f * ((i / 8 / 8) % 8);
    		}
    
    		D3D11_SUBRESOURCE_DATA instanceDataStruct = { 0 };
    		instanceDataStruct.pSysMem = instanceData;
    		instanceDataStruct.SysMemPitch = 0;
    		instanceDataStruct.SysMemSlicePitch = 0;
    		CD3D11_BUFFER_DESC instanceBufferDesc(sizeof(instanceData), D3D11_BIND_VERTEX_BUFFER);
    		DX::ThrowIfFailed(
    			m_deviceResources->GetD3DDevice()->CreateBuffer(
    			&instanceBufferDesc,
    			&instanceDataStruct,
    			&m_instanceBuffer));

    Added this to the Sample3DSceneRenderer declaration:

    Microsoft::WRL::ComPtr<ID3D11Buffer>		m_instanceBuffer;

    Replaced the eye position in Sample3DSceneRenderer::CreateWindowSizeDependentResources():

    static const XMVECTORF32 eye = { 0.0f, 0.7f, 10.5f, 0.0f };

    then, replaced  Sample3DSceneRenderer::Render() with:

    void Sample3DSceneRenderer::Render()
    {
    	// Loading is asynchronous. Only draw geometry after it's loaded.
    	if (!m_loadingComplete)
    	{
    		return;
    	}
    
    	auto context = m_deviceResources->GetD3DDeviceContext();
    
    	// Prepare the constant buffer to send it to the graphics device.
    	context->UpdateSubresource(
    		m_constantBuffer.Get(),
    		0,
    		NULL,
    		&m_constantBufferData,
    		0,
    		0
    		);
    
    	// Each vertex is one instance of the VertexPositionColor struct.
    	UINT stride[] = { sizeof(VertexPositionColor), sizeof(XMFLOAT3) };
    	UINT offset[] = { 0, 0 };
    	ID3D11Buffer* buf[] = { m_vertexBuffer.Get(), m_instanceBuffer.Get() };
    	context->IASetVertexBuffers(
    		0,
    		2,
    		buf,
    		stride,
    		offset);
    
    	context->IASetIndexBuffer(
    		m_indexBuffer.Get(),
    		DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
    		0
    		);
    
    	context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    	context->IASetInputLayout(m_inputLayout.Get());
    
    	// Attach our vertex shader.
    	context->VSSetShader(
    		m_vertexShader.Get(),
    		nullptr,
    		0
    		);
    
    	// Send the constant buffer to the graphics device.
    	context->VSSetConstantBuffers(
    		0,
    		1,
    		m_constantBuffer.GetAddressOf()
    		);
    
    	// Attach our pixel shader.
    	context->PSSetShader(
    		m_pixelShader.Get(),
    		nullptr,
    		0
    		);
    
    	context->DrawIndexedInstanced(m_indexCount, 256,
    		0,
    		0, 0);
    
    	context->DrawIndexedInstanced(m_indexCount, 256,
    		0,
    		0, 256);
    }

    I modified the SimpleVertexShader.hlsl as well:

    cbuffer ModelViewProjectionConstantBuffer : register(b0)
    {
    	matrix model;
    	matrix view;
    	matrix projection;
    };
    
    // Per-vertex data used as input to the vertex shader.
    struct VertexShaderInput
    {
    	float3 pos : POSITION;
    	float3 color : COLOR0;
    	float3 pos2 : POSITION1;
    };
    
    // Per-pixel color data passed through the pixel shader.
    struct PixelShaderInput
    {
    	float4 pos : SV_POSITION;
    	float3 color : COLOR0;
    };
    
    // Simple shader to do vertex processing on the GPU.
    PixelShaderInput main(VertexShaderInput input)
    {
    	PixelShaderInput output;
    	float4 pos = float4(input.pos+input.pos2, 1.0f);
    
    	// Transform the vertex position into projected space.
    	pos = mul(pos, model);
    	pos = mul(pos, view);
    	pos = mul(pos, projection);
    	output.pos = pos;
    
    	// Pass the color through without modification.
    	output.color = input.color;
    
    	return output;
    }

    It draws 512 instances of the cubes when compiled to desktop.

    But when I compile and run on windows phone, only the first maximum 256 instance is visible, no matter what I pass to StartInstanceLocation in DrawIndexedInstanced



    Monday, February 23, 2015 3:45 PM
  • Also, if I replace Sample3DSceneRenderer::Render() with this, in the example above,

    the desktop app draws something (some rectangles as expected), the windows phone app dumps this error to the output window, when DrawInstanced is called:

    D3D11: Removing Device.
    D3D11 WARNING: ID3D11Device::RemoveDevice: Device removal has been triggered for the following reason (DXGI_ERROR_DRIVER_INTERNAL_ERROR: There is strong evidence that the driver has performed an undefined operation; but it may be because the application performed an illegal or undefined operation to begin with.). [ EXECUTION WARNING #379: DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT]

    void Sample3DSceneRenderer::Render()
    {
    	// Loading is asynchronous. Only draw geometry after it's loaded.
    	if (!m_loadingComplete)
    	{
    		return;
    	}
    
    	auto context = m_deviceResources->GetD3DDeviceContext();
    
    	// Prepare the constant buffer to send it to the graphics device.
    	context->UpdateSubresource(
    		m_constantBuffer.Get(),
    		0,
    		NULL,
    		&m_constantBufferData,
    		0,
    		0
    		);
    
    	// Each vertex is one instance of the VertexPositionColor struct.
    	UINT stride[] = { sizeof(VertexPositionColor), sizeof(XMFLOAT3) };
    	UINT offset[] = { 0, 0 };
    	ID3D11Buffer* buf[] = { m_vertexBuffer.Get(), m_instanceBuffer.Get() };
    	context->IASetVertexBuffers(
    		0,
    		2,
    		buf,
    		stride,
    		offset);
    
    	context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    	context->IASetInputLayout(m_inputLayout.Get());
    
    	// Attach our vertex shader.
    	context->VSSetShader(
    		m_vertexShader.Get(),
    		nullptr,
    		0
    		);
    
    	// Send the constant buffer to the graphics device.
    	context->VSSetConstantBuffers(
    		0,
    		1,
    		m_constantBuffer.GetAddressOf()
    		);
    
    	// Attach our pixel shader.
    	context->PSSetShader(
    		m_pixelShader.Get(),
    		nullptr,
    		0
    		);
    
    	context->DrawInstanced(8, 1,
    		0,
    		0);
    }

    Monday, February 23, 2015 3:51 PM
  •      Hi Andras,

     * Have you checked the DirectX Level supported by the Nokia Phone? I got this same error with DirectX level 9-1 and 9-2 when calling DrawIndexedInstanced.

     * What DirectX level was used to compile your shaders?

     * Try running your game using a Warp device and see if the problem is present as well.

         Note that Driver bugs fall under the hardware manufacturer's responsibility.

         I hope it helps!!!

         Tarh Ik

    PS: This posting has been posted "AS IS"

        


    Tarh ik

    Thursday, February 26, 2015 10:18 PM
  • Hi,

    Thanks for the answer.

    Lumia 930 supports DX 11 profile 9.3.

    And the shaders are compiled as Shader Model 4 level 9_3

    A.

    Thursday, February 26, 2015 11:43 PM