3 * Copyright (c) 2007-2010 SlimDX Group
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include "../stack_array.h"
29 #include "BlendState11.h"
30 #include "DepthStencilState11.h"
31 #include "DepthStencilView11.h"
32 #include "OutputMergerWrapper11.h"
33 #include "RenderTargetView11.h"
34 #include "UnorderedAccessView11.h"
36 using namespace System;
42 OutputMergerWrapper::OutputMergerWrapper( ID3D11DeviceContext* device )
45 throw gcnew ArgumentNullException( "device" );
46 deviceContext = device;
49 void OutputMergerWrapper::DepthStencilState::set( SlimDX::Direct3D11::DepthStencilState^ value )
51 ID3D11DepthStencilState* oldState;
53 deviceContext->OMGetDepthStencilState( &oldState, reinterpret_cast<UINT*>( &oldReference ) );
55 if( oldState != NULL )
58 if( value == nullptr )
59 deviceContext->OMSetDepthStencilState( 0, oldReference );
61 deviceContext->OMSetDepthStencilState( value->InternalPointer, oldReference );
64 SlimDX::Direct3D11::DepthStencilState^ OutputMergerWrapper::DepthStencilState::get()
66 ID3D11DepthStencilState* oldState = 0;
68 deviceContext->OMGetDepthStencilState( &oldState, reinterpret_cast<UINT*>( &oldReference ) );
70 if( oldState == NULL )
72 return SlimDX::Direct3D11::DepthStencilState::FromPointer( oldState );
75 void OutputMergerWrapper::DepthStencilReference::set( int value )
77 ID3D11DepthStencilState* oldState = 0;
79 deviceContext->OMGetDepthStencilState( &oldState, reinterpret_cast<UINT*>( &oldReference ) );
80 deviceContext->OMSetDepthStencilState( oldState, value );
82 if( oldState != NULL )
86 int OutputMergerWrapper::DepthStencilReference::get()
88 ID3D11DepthStencilState* oldState = 0;
90 deviceContext->OMGetDepthStencilState( &oldState, reinterpret_cast<UINT*>( &oldReference ) );
92 if( oldState != NULL )
98 void OutputMergerWrapper::BlendState::set( SlimDX::Direct3D11::BlendState^ value )
100 ID3D11BlendState* oldState = 0;
103 deviceContext->OMGetBlendState( &oldState, oldFactor, reinterpret_cast<UINT*>( &oldMask ) );
105 if( oldState != NULL )
108 if( value == nullptr )
109 deviceContext->OMSetBlendState( 0, oldFactor, oldMask );
111 deviceContext->OMSetBlendState( value->InternalPointer, oldFactor, oldMask );
114 SlimDX::Direct3D11::BlendState^ OutputMergerWrapper::BlendState::get()
116 ID3D11BlendState* oldState = 0;
119 deviceContext->OMGetBlendState( &oldState, oldFactor, reinterpret_cast<UINT*>( &oldMask ) );
121 return SlimDX::Direct3D11::BlendState::FromPointer( oldState );
124 void OutputMergerWrapper::BlendFactor::set( Color4 value )
126 ID3D11BlendState* oldState = 0;
129 deviceContext->OMGetBlendState( &oldState, oldFactor, reinterpret_cast<UINT*>( &oldMask ) );
131 float newFactor[4] = { value.Red, value.Green, value.Blue, value.Alpha };
132 deviceContext->OMSetBlendState( oldState, newFactor, oldMask );
134 if( oldState != NULL )
138 Color4 OutputMergerWrapper::BlendFactor::get()
140 ID3D11BlendState* oldState = 0;
143 deviceContext->OMGetBlendState( &oldState, oldFactor, reinterpret_cast<UINT*>( &oldMask ) );
145 if( oldState != NULL )
148 return Color4( oldFactor[3], oldFactor[0], oldFactor[1], oldFactor[2] );
151 void OutputMergerWrapper::BlendSampleMask::set( int value )
153 ID3D11BlendState* oldState = 0;
156 deviceContext->OMGetBlendState( &oldState, oldFactor, reinterpret_cast<UINT*>( &oldMask ) );
157 deviceContext->OMSetBlendState( oldState, oldFactor, value );
159 if( oldState != NULL )
163 int OutputMergerWrapper::BlendSampleMask::get()
165 ID3D11BlendState* oldState = 0;
168 deviceContext->OMGetBlendState( &oldState, oldFactor, reinterpret_cast<UINT*>( &oldMask ) );
170 if( oldState != NULL )
176 void OutputMergerWrapper::SetTargets( RenderTargetView^ renderTargetView )
178 SetTargets( nullptr, renderTargetView );
181 void OutputMergerWrapper::SetTargets( DepthStencilView^ depthStencilView, RenderTargetView^ renderTargetView )
183 ID3D11DepthStencilView *nativeDSV = depthStencilView == nullptr ? 0 : static_cast<ID3D11DepthStencilView*>( depthStencilView->InternalPointer );
184 ID3D11RenderTargetView *nativeRTV[] = { renderTargetView == nullptr ? 0 : static_cast<ID3D11RenderTargetView*>( renderTargetView->InternalPointer ) };
186 deviceContext->OMSetRenderTargets( 1, nativeRTV, nativeDSV );
189 void OutputMergerWrapper::SetTargets( ... array<RenderTargetView^>^ renderTargets )
191 SetTargets( nullptr, renderTargets );
194 void OutputMergerWrapper::SetTargets( DepthStencilView^ depthStencilView, ... array<RenderTargetView^>^ renderTargets )
196 ID3D11DepthStencilView *nativeDSV = depthStencilView == nullptr ? 0 : static_cast<ID3D11DepthStencilView*>( depthStencilView->InternalPointer );
197 ID3D11RenderTargetView* nativeRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
199 if( renderTargets == nullptr )
201 deviceContext->OMSetRenderTargets( 0, 0, nativeDSV );
205 for( int i = 0; i < renderTargets->Length; ++i )
206 nativeRTVs[ i ] = renderTargets[ i ] == nullptr ? 0 : static_cast<ID3D11RenderTargetView*>( renderTargets[ i ]->InternalPointer );
207 deviceContext->OMSetRenderTargets( renderTargets->Length, nativeRTVs, nativeDSV );
211 void OutputMergerWrapper::SetTargets( RenderTargetView^ renderTargetView, int startSlot, array<UnorderedAccessView^>^ unorderedAccessViews )
213 array<int>^ lengths = gcnew array<int>( unorderedAccessViews->Length );
214 for( int i = 0; i < unorderedAccessViews->Length; i++ )
217 SetTargets( nullptr, renderTargetView, startSlot, unorderedAccessViews, lengths );
220 void OutputMergerWrapper::SetTargets( DepthStencilView^ depthStencilView, RenderTargetView^ renderTargetView, int startSlot, array<UnorderedAccessView^>^ unorderedAccessViews )
222 array<int>^ lengths = gcnew array<int>( unorderedAccessViews->Length );
223 for( int i = 0; i < unorderedAccessViews->Length; i++ )
226 SetTargets( depthStencilView, renderTargetView, startSlot, unorderedAccessViews, lengths );
229 void OutputMergerWrapper::SetTargets( int startSlot, array<UnorderedAccessView^>^ unorderedAccessViews, ... array<RenderTargetView^>^ renderTargets )
231 array<int>^ lengths = gcnew array<int>( unorderedAccessViews->Length );
232 for( int i = 0; i < unorderedAccessViews->Length; i++ )
235 SetTargets( nullptr, startSlot, unorderedAccessViews, lengths, renderTargets );
238 void OutputMergerWrapper::SetTargets( DepthStencilView^ depthStencilView, int startSlot, array<UnorderedAccessView^>^ unorderedAccessViews, ... array<RenderTargetView^>^ renderTargets )
240 array<int>^ lengths = gcnew array<int>( unorderedAccessViews->Length );
241 for( int i = 0; i < unorderedAccessViews->Length; i++ )
244 SetTargets( depthStencilView, startSlot, unorderedAccessViews, lengths, renderTargets );
247 void OutputMergerWrapper::SetTargets( RenderTargetView^ renderTargetView, int startSlot, array<UnorderedAccessView^>^ unorderedAccessViews, array<int>^ lengths )
249 SetTargets( nullptr, renderTargetView, startSlot, unorderedAccessViews, lengths );
252 void OutputMergerWrapper::SetTargets( DepthStencilView^ depthStencilView, RenderTargetView^ renderTargetView, int startSlot, array<UnorderedAccessView^>^ unorderedAccessViews, array<int>^ initialLengths )
254 ID3D11DepthStencilView *nativeDSV = depthStencilView == nullptr ? 0 : static_cast<ID3D11DepthStencilView*>( depthStencilView->InternalPointer );
255 ID3D11RenderTargetView *nativeRTV[] = { renderTargetView == nullptr ? 0 : static_cast<ID3D11RenderTargetView*>( renderTargetView->InternalPointer ) };
257 stack_array<ID3D11UnorderedAccessView*> uavs = stackalloc( ID3D11UnorderedAccessView*, unorderedAccessViews->Length );
258 for( int i = 0; i < unorderedAccessViews->Length; i++ )
259 uavs[i] = unorderedAccessViews[i]->InternalPointer;
261 pin_ptr<int> pinnedLengths = &initialLengths[0];
262 deviceContext->OMSetRenderTargetsAndUnorderedAccessViews( 1, nativeRTV, nativeDSV, startSlot, unorderedAccessViews->Length, &uavs[0], reinterpret_cast<UINT*>( pinnedLengths ) );
265 void OutputMergerWrapper::SetTargets( int startSlot, array<UnorderedAccessView^>^ unorderedAccessViews, array<int>^ initialLengths, ... array<RenderTargetView^>^ renderTargets )
267 SetTargets( nullptr, startSlot, unorderedAccessViews, initialLengths, renderTargets );
270 void OutputMergerWrapper::SetTargets( DepthStencilView^ depthStencilView, int startSlot, array<UnorderedAccessView^>^ unorderedAccessViews, array<int>^ initialLengths, ... array<RenderTargetView^>^ renderTargets )
272 ID3D11DepthStencilView *nativeDSV = depthStencilView == nullptr ? 0 : static_cast<ID3D11DepthStencilView*>( depthStencilView->InternalPointer );
273 ID3D11RenderTargetView* nativeRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
275 stack_array<ID3D11UnorderedAccessView*> uavs = stackalloc( ID3D11UnorderedAccessView*, unorderedAccessViews->Length );
276 for( int i = 0; i < unorderedAccessViews->Length; i++ )
277 uavs[i] = unorderedAccessViews[i]->InternalPointer;
279 pin_ptr<int> pinnedLengths = &initialLengths[0];
280 if( renderTargets == nullptr )
282 deviceContext->OMSetRenderTargetsAndUnorderedAccessViews( 0, 0, nativeDSV, startSlot, unorderedAccessViews->Length, &uavs[0], reinterpret_cast<UINT*>( pinnedLengths ) );
286 for( int i = 0; i < renderTargets->Length; ++i )
287 nativeRTVs[ i ] = renderTargets[ i ] == nullptr ? 0 : static_cast<ID3D11RenderTargetView*>( renderTargets[ i ]->InternalPointer );
288 deviceContext->OMSetRenderTargetsAndUnorderedAccessViews( renderTargets->Length, nativeRTVs, nativeDSV, startSlot, unorderedAccessViews->Length, &uavs[0], reinterpret_cast<UINT*>( pinnedLengths ) );
292 DepthStencilView^ OutputMergerWrapper::GetDepthStencilView()
294 ID3D11DepthStencilView *view;
296 deviceContext->OMGetRenderTargets( 0, NULL, &view );
297 return DepthStencilView::FromPointer( view );
300 array<RenderTargetView^>^ OutputMergerWrapper::GetRenderTargets( int count )
302 stack_array<ID3D11RenderTargetView*> targets = stackalloc( ID3D11RenderTargetView*, count );
303 array<RenderTargetView^>^ results = gcnew array<RenderTargetView^>( count );
305 deviceContext->OMGetRenderTargets( count, &targets[0], NULL );
307 for( int i = 0; i < count; i++ )
308 results[i] = RenderTargetView::FromPointer( targets[i] );
313 array<UnorderedAccessView^>^ OutputMergerWrapper::GetUnorderedAccessViews( int startSlot, int count )
315 stack_array<ID3D11UnorderedAccessView*> targets = stackalloc( ID3D11UnorderedAccessView*, count );
316 array<UnorderedAccessView^>^ results = gcnew array<UnorderedAccessView^>( count );
318 deviceContext->OMGetRenderTargetsAndUnorderedAccessViews( 0, NULL, NULL, startSlot, count, &targets[0] );
320 for( int i = 0; i < count; i++ )
321 results[i] = UnorderedAccessView::FromPointer( targets[i] );