Access violation in DirectX OMSetRenderTargets
- by IDWMaster
I receive the following error (Unhandled exception at 0x527DAE81 (d3d11_1sdklayers.dll) in Lesson2.Triangles.exe: 0xC0000005: Access violation reading location 0x00000000) when running the Triangle sample application for DirectX 11 in D3D_FEATURE_LEVEL_9_1. This error occurs at the OMSetRenderTargets function, as shown below, and does not happen if I remove that function from the program (but then, the screen is blue, and does not render the triangle)
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved
#include
#include
#include "DirectXSample.h"
#include "BasicMath.h"
#include "BasicReaderWriter.h"
using namespace Microsoft::WRL;
using namespace Windows::UI::Core;
using namespace Windows::Foundation;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Infrastructure;
// This class defines the application as a whole.
ref class Direct3DTutorialViewProvider : public IViewProvider
{
private:
CoreWindow^ m_window;
ComPtr m_swapChain;
ComPtr m_d3dDevice;
ComPtr m_d3dDeviceContext;
ComPtr m_renderTargetView;
public:
// This method is called on application launch.
void Initialize(
_In_ CoreWindow^ window,
_In_ CoreApplicationView^ applicationView
)
{
m_window = window;
}
// This method is called after Initialize.
void Load(_In_ Platform::String^ entryPoint)
{
}
// This method is called after Load.
void Run()
{
// First, create the Direct3D device.
// This flag is required in order to enable compatibility with Direct2D.
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#if defined(_DEBUG)
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
// This array defines the ordering of feature levels that D3D should attempt to create.
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_1
};
ComPtr d3dDevice;
ComPtr d3dDeviceContext;
DX::ThrowIfFailed(
D3D11CreateDevice(
nullptr, // specify nullptr to use the default adapter
D3D_DRIVER_TYPE_HARDWARE,
nullptr, // leave as nullptr if hardware is used
creationFlags, // optionally set debug and Direct2D compatibility flags
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION, // always set this to D3D11_SDK_VERSION
&d3dDevice,
nullptr,
&d3dDeviceContext
)
);
// Retrieve the Direct3D 11.1 interfaces.
DX::ThrowIfFailed(
d3dDevice.As(&m_d3dDevice)
);
DX::ThrowIfFailed(
d3dDeviceContext.As(&m_d3dDeviceContext)
);
// After the D3D device is created, create additional application resources.
CreateWindowSizeDependentResources();
// Create a Basic Reader-Writer class to load data from disk. This class is examined
// in the Resource Loading sample.
BasicReaderWriter^ reader = ref new BasicReaderWriter();
// Load the raw vertex shader bytecode from disk and create a vertex shader with it.
auto vertexShaderBytecode = reader-ReadData("SimpleVertexShader.cso");
ComPtr vertexShader;
DX::ThrowIfFailed(
m_d3dDevice-CreateVertexShader(
vertexShaderBytecode-Data,
vertexShaderBytecode-Length,
nullptr,
&vertexShader
)
);
// Create an input layout that matches the layout defined in the vertex shader code.
// For this lesson, this is simply a float2 vector defining the vertex position.
const D3D11_INPUT_ELEMENT_DESC basicVertexLayoutDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
ComPtr inputLayout;
DX::ThrowIfFailed(
m_d3dDevice-CreateInputLayout(
basicVertexLayoutDesc,
ARRAYSIZE(basicVertexLayoutDesc),
vertexShaderBytecode-Data,
vertexShaderBytecode-Length,
&inputLayout
)
);
// Load the raw pixel shader bytecode from disk and create a pixel shader with it.
auto pixelShaderBytecode = reader-ReadData("SimplePixelShader.cso");
ComPtr pixelShader;
DX::ThrowIfFailed(
m_d3dDevice-CreatePixelShader(
pixelShaderBytecode-Data,
pixelShaderBytecode-Length,
nullptr,
&pixelShader
)
);
// Create vertex and index buffers that define a simple triangle.
float3 triangleVertices[] =
{
float3(-0.5f, -0.5f,13.5f),
float3( 0.0f, 0.5f,0),
float3( 0.5f, -0.5f,0),
};
D3D11_BUFFER_DESC vertexBufferDesc = {0};
vertexBufferDesc.ByteWidth = sizeof(float3) * ARRAYSIZE(triangleVertices);
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData;
vertexBufferData.pSysMem = triangleVertices;
vertexBufferData.SysMemPitch = 0;
vertexBufferData.SysMemSlicePitch = 0;
ComPtr vertexBuffer;
DX::ThrowIfFailed(
m_d3dDevice-CreateBuffer(
&vertexBufferDesc,
&vertexBufferData,
&vertexBuffer
)
);
// Once all D3D resources are created, configure the application window.
// Allow the application to respond when the window size changes.
m_window-SizeChanged +=
ref new TypedEventHandler(
this,
&Direct3DTutorialViewProvider::OnWindowSizeChanged
);
// Specify the cursor type as the standard arrow cursor.
m_window-PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
// Activate the application window, making it visible and enabling it to receive events.
m_window-Activate();
// Enter the render loop. Note that tailored applications should never exit.
while (true)
{
// Process events incoming to the window.
m_window-Dispatcher-ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
// Specify the render target we created as the output target.
ID3D11RenderTargetView* targets[1] = {m_renderTargetView.Get()};
m_d3dDeviceContext-OMSetRenderTargets(
1,
targets,
NULL // use no depth stencil
);
// Clear the render target to a solid color.
const float clearColor[4] = { 0.071f, 0.04f, 0.561f, 1.0f };
//Code fails here
m_d3dDeviceContext-ClearRenderTargetView(
m_renderTargetView.Get(),
clearColor
);
m_d3dDeviceContext-IASetInputLayout(inputLayout.Get());
// Set the vertex and index buffers, and specify the way they define geometry.
UINT stride = sizeof(float3);
UINT offset = 0;
m_d3dDeviceContext-IASetVertexBuffers(
0,
1,
vertexBuffer.GetAddressOf(),
&stride,
&offset
);
m_d3dDeviceContext-IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Set the vertex and pixel shader stage state.
m_d3dDeviceContext-VSSetShader(
vertexShader.Get(),
nullptr,
0
);
m_d3dDeviceContext-PSSetShader(
pixelShader.Get(),
nullptr,
0
);
// Draw the cube.
m_d3dDeviceContext-Draw(3,0);
// Present the rendered image to the window. Because the maximum frame latency is set to 1,
// the render loop will generally be throttled to the screen refresh rate, typically around
// 60Hz, by sleeping the application on Present until the screen is refreshed.
DX::ThrowIfFailed(
m_swapChain-Present(1, 0)
);
}
}
// This method is called before the application exits.
void Uninitialize()
{
}
private:
// This method is called whenever the application window size changes.
void OnWindowSizeChanged(
_In_ CoreWindow^ sender,
_In_ WindowSizeChangedEventArgs^ args
)
{
m_renderTargetView = nullptr;
CreateWindowSizeDependentResources();
}
// This method creates all application resources that depend on
// the application window size. It is called at app initialization,
// and whenever the application window size changes.
void CreateWindowSizeDependentResources()
{
if (m_swapChain != nullptr)
{
// If the swap chain already exists, resize it.
DX::ThrowIfFailed(
m_swapChain-ResizeBuffers(
2,
0,
0,
DXGI_FORMAT_R8G8B8A8_UNORM,
0
)
);
}
else
{
// If the swap chain does not exist, create it.
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
swapChainDesc.Stereo = false;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.Scaling = DXGI_SCALING_NONE;
swapChainDesc.Flags = 0;
// Use automatic sizing.
swapChainDesc.Width = 0;
swapChainDesc.Height = 0;
// This is the most common swap chain format.
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
// Don't use multi-sampling.
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
// Use two buffers to enable flip effect.
swapChainDesc.BufferCount = 2;
// We recommend using this swap effect for all applications.
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
// Once the swap chain description is configured, it must be
// created on the same adapter as the existing D3D Device.
// First, retrieve the underlying DXGI Device from the D3D Device.
ComPtr dxgiDevice;
DX::ThrowIfFailed(
m_d3dDevice.As(&dxgiDevice)
);
// Ensure that DXGI does not queue more than one frame at a time. This both reduces
// latency and ensures that the application will only render after each VSync, minimizing
// power consumption.
DX::ThrowIfFailed(
dxgiDevice-SetMaximumFrameLatency(1)
);
// Next, get the parent factory from the DXGI Device.
ComPtr dxgiAdapter;
DX::ThrowIfFailed(
dxgiDevice-GetAdapter(&dxgiAdapter)
);
ComPtr dxgiFactory;
DX::ThrowIfFailed(
dxgiAdapter-GetParent(
__uuidof(IDXGIFactory2),
&dxgiFactory
)
);
// Finally, create the swap chain.
DX::ThrowIfFailed(
dxgiFactory-CreateSwapChainForImmersiveWindow(
m_d3dDevice.Get(),
DX::GetIUnknown(m_window),
&swapChainDesc,
nullptr, // allow on all displays
&m_swapChain
)
);
}
// Once the swap chain is created, create a render target view. This will
// allow Direct3D to render graphics to the window.
ComPtr backBuffer;
DX::ThrowIfFailed(
m_swapChain-GetBuffer(
0,
__uuidof(ID3D11Texture2D),
&backBuffer
)
);
DX::ThrowIfFailed(
m_d3dDevice-CreateRenderTargetView(
backBuffer.Get(),
nullptr,
&m_renderTargetView
)
);
// After the render target view is created, specify that the viewport,
// which describes what portion of the window to draw to, should cover
// the entire window.
D3D11_TEXTURE2D_DESC backBufferDesc = {0};
backBuffer-GetDesc(&backBufferDesc);
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
viewport.Width = static_cast(backBufferDesc.Width);
viewport.Height = static_cast(backBufferDesc.Height);
viewport.MinDepth = D3D11_MIN_DEPTH;
viewport.MaxDepth = D3D11_MAX_DEPTH;
m_d3dDeviceContext-RSSetViewports(1, &viewport);
}
};
// This class defines how to create the custom View Provider defined above.
ref class Direct3DTutorialViewProviderFactory : IViewProviderFactory
{
public:
IViewProvider^ CreateViewProvider()
{
return ref new Direct3DTutorialViewProvider();
}
};
[Platform::MTAThread]
int main(array^)
{
auto viewProviderFactory = ref new Direct3DTutorialViewProviderFactory();
Windows::ApplicationModel::Core::CoreApplication::Run(viewProviderFactory);
return 0;
}