swapchain , context 和 device 的区别与联系
除此篇随笔外, 还有另外一篇转载: http://www.cnblogs.com/Wilson-Loo/articles/2797613.html
一些概念, 特别是 IT 领域的, 尤其需要弄明白其本质、工作特点、机制后, 才能更好地去使用; 才不会在编码过程中 思考于为什么要这样调用呢, 为什么一定是 device_>createBuffer() 而不能是 context_->createBuffer() 呢?!此番会将经历浪费在无谓的思考上, 不能专注于当下的整个项目工作; 但有思考还好啦, 说明还是有改善、进修的契机; 可怕的是 仅仅是照着 Tutorials教程 一个个单词的抄着, 或者 copy + C/V, 待整本书抄完了, 就好像学会了似的。
以前在 还没有看 《effective c++》 系列书籍 的时候, 看别人代码是总是不明白为什么要 在 函数参数列表的括号 右边使用 冒号, 然后又应用各种古怪的表示( 呃, 构造函数的 初始化参数列表); 没看《设计模式》前, 总是纳闷代码间 为什么要那样组织, 像helloword 那样不是很清爽的吗!
后来才明白其中的原委, 机制, 处于什么考量, 渐渐的自己的编写的代码方式 也随着改变, 看别人代码时 也很容易“入眼”, 更多的时间花在了有用的书本 正确观点的 阅读学习上, 而不会纠结于 “这本书的纸张颜色为什么不是 黄色的呢?”! 这些自杀式自我思考。
回到正题, 经我 这两个星期来的学习, 对 context, device 和 swapchain 的区别 和联系 有了如下的认识, 加深了自己的认知。
context :设备上下文, 用来渲染 指令的。 作为 操作相关处理的“接口”而非对象, 正如下图:
device 作为 “实际对象”, 管理存储各种数据(当然也负责与 hardwar的沟通), 而 context 更多的是 “提供操作的接口”, 通常用来告知 device 进行如何绘图 how to draw, 正如
http://msdn.microsoft.com/zh-cn/library/windows/desktop/hh404598(v=vs.85).aspx
所说: The device context interface represents a device context; it is used to render commands. 通过 ID3D11DeviceContext 接口的函数可知:
Methods The ID3D11DeviceContext1 interface has these methods. ------------------------------------------------------ Method() // Description ClearView() // Sets all the elements in a resource view to one value. CopySubresourceRegion1() // Copies a region from a source resource to a destination resource. CSGetConstantBuffers1() // Gets the constant buffers that the compute-shader stage uses. CSSetConstantBuffers1() // Sets the constant buffers that the compute-shader stage uses. DiscardResource() // Discards a resource from the device context. DiscardView() // Discards a resource view from the device context. DiscardView1() // Discards the specified elements in a resource view from the device context. DSGetConstantBuffers1() // Gets the constant buffers that the domain-shader stage uses. DSSetConstantBuffers1() // Sets the constant buffers that the domain-shader stage uses. GSGetConstantBuffers1() // Gets the constant buffers that the geometry shader pipeline stage uses. GSSetConstantBuffers1() // Sets the constant buffers that the geometry shader pipeline stage uses. HSGetConstantBuffers1() // Gets the constant buffers that the hull-shader stage uses. HSSetConstantBuffers1() // Sets the constant buffers that the hull-shader stage of the pipeline uses. PSGetConstantBuffers1() // Gets the constant buffers that the pixel shader pipeline stage uses. PSSetConstantBuffers1() // Sets the constant buffers that the pixel shader pipeline stage uses. SwapDeviceContextState() // Activates the given context state object and changes the current device behavior to Direct3D 11, Direct3D 10.1, or Direct3D 10. UpdateSubresource1() // The CPU copies data from memory to a subresource created in non-mappable memory. VSGetConstantBuffers1() // Gets the constant buffers that the vertex shader pipeline stage uses. VSSetConstantBuffers1() // Sets the constant buffers that the vertex shader pipeline stage uses.
这些函数都几乎是 用来 操作(已存在的数据相关的)数据, 而不会创建数据、对象。例如前面我们已经使用到的
d3dContext_->OMSetRenderTargets( 1, &backBufferTarget_, 0 ); d3dContext_->RSSetViewports( 1, &viewport); d3dContext_->ClearRenderTargetView( backBufferTarget_, clearColor); //还有后面用到的: d3dContext_->IASetInputLayout( inputLayout); d3dContext_->IASetVertexBuffer( 0, &vertexBuffer_, &stride, &offset); d3dContext_->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); d3dContext_->VSSetShader( solidColorVS, 0, 0); d3dContext_->PSSetShader( solidColorPS, 0, 0); d3dContext_->Draw( 3, 0);
第二,device 就是一个虚拟适配器, 和硬件交互, 用力创建资源:
http://msdn.microsoft.com/zh-cn/library/windows/desktop/ff476379(v=vs.85).aspx
The device interface represents a virtual adapter; it is used to create resources.
// 前面使用到的: d3dDevice_->CreateRenderTargetView( backBufferTexture, 0, &backBufferTarget_); d3dDevice_->CreateBuffer( &vertexDesc, &resourceData, &vertexBuffer); d3dDevice_->CreateVertexShader( vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), 0, &solidColorVS); d3dDevice_->CreatePixelShader( psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(), 0, &solidColorPS);d3dDevice_->CreateInputLayout( vertexLayout, totalLayoutElements, vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(), &inputLayout); // 后面使用的: d3dDevice_->CreateSampleState( &colorMapDesc, &colormapSampler_); d3dDevice_->CreateBlendState( &blendDesc, &alphaBlendState_ );
第三, swapchain 实现了一个或多个的 surface 用来存储 输出到输出设备output device 之前的各种 “渲染数据”, 做得数据后台加速:
http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb174569(v=vs.85).aspx
An IDXGISwapChain interface implements one or more surfaces for storing renderd data before presenting it to an output.
Methods The IDXGISwapChain interface has these methods. --------------------------------------- Method Description GetBuffer() // Accesses one of the swap-chain's back buffers. GetContainingOutput() // Get the output (the display monitor) that contains the majority of the client area of the target window. GetDesc() // Get a description of the swap chain. // Note Starting with Direct3D 11.1, we recommend not to use GetDesc anymore to get a description of the swap chain. Instead, use IDXGISwapChain1::GetDesc1. GetFrameStatistics() // Gets performance statistics about the last render frame. GetFullscreenState() // Get the state associated with full-screen mode. GetLastPresentCount() // Gets the number of times that IDXGISwapChain::Present or IDXGISwapChain1::Present1 has been called. Present() // Presents a rendered image to the user. // Note Starting with Direct3D 11.1, we recommend not to use Present anymore to present a rendered image. Instead, use IDXGISwapChain1::Present1. For more info, see Remarks. ResizeBuffers() // Changes the swap chain's back buffer size, format, and number of buffers. This should be called when the application window is resized. ResizeTarget() // Resizes the output target.
大部分 函数都是 与 buffer的状态相关, 不像 device的 createXXX() 创建对象, 也不像context 的 SetYYY() 设置较大功能。
另外, 从本随笔开头的图可看出, context 大部分的 “动词”, device 是 “名词”的创建/管理, 而swapchain 就是缓冲加速器。
-- the end.