DeviceAttachmentsD3D11.cpp (9037B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "DeviceAttachmentsD3D11.h" 8 #include "mozilla/gfx/Logging.h" 9 #include "mozilla/layers/Compositor.h" 10 #include "CompositorD3D11Shaders.h" 11 #include "ShaderDefinitionsD3D11.h" 12 13 namespace mozilla { 14 namespace layers { 15 16 using namespace gfx; 17 18 DeviceAttachmentsD3D11::DeviceAttachmentsD3D11(ID3D11Device* device) 19 : mDevice(device), 20 mContinueInit(true), 21 mInitialized(false), 22 mDeviceReset(false) {} 23 24 DeviceAttachmentsD3D11::~DeviceAttachmentsD3D11() {} 25 26 /* static */ 27 RefPtr<DeviceAttachmentsD3D11> DeviceAttachmentsD3D11::Create( 28 ID3D11Device* aDevice) { 29 // We don't return null even if the attachments object even if it fails to 30 // initialize, so the compositor can grab the failure ID. 31 RefPtr<DeviceAttachmentsD3D11> attachments = 32 new DeviceAttachmentsD3D11(aDevice); 33 attachments->Initialize(); 34 return attachments.forget(); 35 } 36 37 bool DeviceAttachmentsD3D11::Initialize() { 38 D3D11_INPUT_ELEMENT_DESC layout[] = { 39 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, 40 D3D11_INPUT_PER_VERTEX_DATA, 0}, 41 }; 42 43 HRESULT hr; 44 hr = mDevice->CreateInputLayout( 45 layout, sizeof(layout) / sizeof(D3D11_INPUT_ELEMENT_DESC), LayerQuadVS, 46 sizeof(LayerQuadVS), getter_AddRefs(mInputLayout)); 47 48 if (Failed(hr, "CreateInputLayout")) { 49 mInitFailureId = "FEATURE_FAILURE_D3D11_INPUT_LAYOUT"; 50 return false; 51 } 52 53 Vertex vertices[] = {{{0.0, 0.0}}, {{1.0, 0.0}}, {{0.0, 1.0}}, {{1.0, 1.0}}}; 54 CD3D11_BUFFER_DESC bufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER); 55 D3D11_SUBRESOURCE_DATA data; 56 data.pSysMem = (void*)vertices; 57 58 hr = mDevice->CreateBuffer(&bufferDesc, &data, getter_AddRefs(mVertexBuffer)); 59 if (Failed(hr, "create vertex buffer")) { 60 mInitFailureId = "FEATURE_FAILURE_D3D11_VERTEX_BUFFER"; 61 return false; 62 } 63 if (!CreateShaders()) { 64 mInitFailureId = "FEATURE_FAILURE_D3D11_CREATE_SHADERS"; 65 return false; 66 } 67 68 CD3D11_BUFFER_DESC cBufferDesc(sizeof(VertexShaderConstants), 69 D3D11_BIND_CONSTANT_BUFFER, 70 D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); 71 72 hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, 73 getter_AddRefs(mVSConstantBuffer)); 74 if (Failed(hr, "create vs buffer")) { 75 mInitFailureId = "FEATURE_FAILURE_D3D11_VS_BUFFER"; 76 return false; 77 } 78 79 cBufferDesc.ByteWidth = sizeof(PixelShaderConstants); 80 hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, 81 getter_AddRefs(mPSConstantBuffer)); 82 if (Failed(hr, "create ps buffer")) { 83 mInitFailureId = "FEATURE_FAILURE_D3D11_PS_BUFFER"; 84 return false; 85 } 86 87 CD3D11_RASTERIZER_DESC rastDesc(D3D11_DEFAULT); 88 rastDesc.CullMode = D3D11_CULL_NONE; 89 rastDesc.ScissorEnable = TRUE; 90 91 hr = mDevice->CreateRasterizerState(&rastDesc, 92 getter_AddRefs(mRasterizerState)); 93 if (Failed(hr, "create rasterizer")) { 94 mInitFailureId = "FEATURE_FAILURE_D3D11_RASTERIZER"; 95 return false; 96 } 97 98 CD3D11_SAMPLER_DESC samplerDesc(D3D11_DEFAULT); 99 hr = mDevice->CreateSamplerState(&samplerDesc, 100 getter_AddRefs(mLinearSamplerState)); 101 if (Failed(hr, "create linear sampler")) { 102 mInitFailureId = "FEATURE_FAILURE_D3D11_LINEAR_SAMPLER"; 103 return false; 104 } 105 106 samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; 107 hr = mDevice->CreateSamplerState(&samplerDesc, 108 getter_AddRefs(mPointSamplerState)); 109 if (Failed(hr, "create point sampler")) { 110 mInitFailureId = "FEATURE_FAILURE_D3D11_POINT_SAMPLER"; 111 return false; 112 } 113 114 CD3D11_BLEND_DESC blendDesc(D3D11_DEFAULT); 115 D3D11_RENDER_TARGET_BLEND_DESC rtBlendPremul = {TRUE, 116 D3D11_BLEND_ONE, 117 D3D11_BLEND_INV_SRC_ALPHA, 118 D3D11_BLEND_OP_ADD, 119 D3D11_BLEND_ONE, 120 D3D11_BLEND_INV_SRC_ALPHA, 121 D3D11_BLEND_OP_ADD, 122 D3D11_COLOR_WRITE_ENABLE_ALL}; 123 blendDesc.RenderTarget[0] = rtBlendPremul; 124 hr = mDevice->CreateBlendState(&blendDesc, getter_AddRefs(mPremulBlendState)); 125 if (Failed(hr, "create pm blender")) { 126 mInitFailureId = "FEATURE_FAILURE_D3D11_PM_BLENDER"; 127 return false; 128 } 129 130 D3D11_RENDER_TARGET_BLEND_DESC rtCopyPremul = {TRUE, 131 D3D11_BLEND_ONE, 132 D3D11_BLEND_ZERO, 133 D3D11_BLEND_OP_ADD, 134 D3D11_BLEND_ONE, 135 D3D11_BLEND_ZERO, 136 D3D11_BLEND_OP_ADD, 137 D3D11_COLOR_WRITE_ENABLE_ALL}; 138 blendDesc.RenderTarget[0] = rtCopyPremul; 139 hr = mDevice->CreateBlendState(&blendDesc, getter_AddRefs(mPremulCopyState)); 140 if (Failed(hr, "create pm copy blender")) { 141 mInitFailureId = "FEATURE_FAILURE_D3D11_PM_COPY_BLENDER"; 142 return false; 143 } 144 145 D3D11_RENDER_TARGET_BLEND_DESC rtBlendNonPremul = { 146 TRUE, 147 D3D11_BLEND_SRC_ALPHA, 148 D3D11_BLEND_INV_SRC_ALPHA, 149 D3D11_BLEND_OP_ADD, 150 D3D11_BLEND_ONE, 151 D3D11_BLEND_INV_SRC_ALPHA, 152 D3D11_BLEND_OP_ADD, 153 D3D11_COLOR_WRITE_ENABLE_ALL}; 154 blendDesc.RenderTarget[0] = rtBlendNonPremul; 155 hr = mDevice->CreateBlendState(&blendDesc, 156 getter_AddRefs(mNonPremulBlendState)); 157 if (Failed(hr, "create npm blender")) { 158 mInitFailureId = "FEATURE_FAILURE_D3D11_NPM_BLENDER"; 159 return false; 160 } 161 162 D3D11_RENDER_TARGET_BLEND_DESC rtBlendDisabled = { 163 FALSE, 164 D3D11_BLEND_SRC_ALPHA, 165 D3D11_BLEND_INV_SRC_ALPHA, 166 D3D11_BLEND_OP_ADD, 167 D3D11_BLEND_ONE, 168 D3D11_BLEND_INV_SRC_ALPHA, 169 D3D11_BLEND_OP_ADD, 170 D3D11_COLOR_WRITE_ENABLE_ALL}; 171 blendDesc.RenderTarget[0] = rtBlendDisabled; 172 hr = mDevice->CreateBlendState(&blendDesc, 173 getter_AddRefs(mDisabledBlendState)); 174 if (Failed(hr, "create null blender")) { 175 mInitFailureId = "FEATURE_FAILURE_D3D11_NULL_BLENDER"; 176 return false; 177 } 178 179 if (!InitSyncObject()) { 180 mInitFailureId = "FEATURE_FAILURE_D3D11_OBJ_SYNC"; 181 return false; 182 } 183 184 mInitialized = true; 185 return true; 186 } 187 188 bool DeviceAttachmentsD3D11::InitSyncObject() { 189 // Sync object is not supported on WARP. 190 if (DeviceManagerDx::Get()->IsWARP()) { 191 return true; 192 } 193 194 MOZ_ASSERT(!mSyncObject); 195 MOZ_ASSERT(mDevice); 196 197 mSyncObject = SyncObjectHost::CreateSyncObjectHost(mDevice); 198 MOZ_ASSERT(mSyncObject); 199 200 return mSyncObject->Init(); 201 } 202 203 bool DeviceAttachmentsD3D11::CreateShaders() { 204 InitVertexShader(sLayerQuadVS, mVSQuadShader, ClipType::ClipNone); 205 InitVertexShader(sLayerQuadClipVS, mVSQuadShader, ClipType::RoundedRect); 206 207 InitPixelShader(sSolidColorShader, getter_AddRefs(mSolidColorShader)); 208 InitPixelShader(sRGBShader, mRGBShader, ClipType::ClipNone); 209 InitPixelShader(sRGBClipShader, mRGBShader, ClipType::RoundedRect); 210 InitPixelShader(sRGBAShader, mRGBAShader, ClipType::ClipNone); 211 InitPixelShader(sRGBAClipShader, mRGBAShader, ClipType::RoundedRect); 212 InitPixelShader(sYCbCrShader, mYCbCrShader, ClipType::ClipNone); 213 InitPixelShader(sYCbCrClipShader, mYCbCrShader, ClipType::RoundedRect); 214 InitPixelShader(sNV12Shader, mNV12Shader, ClipType::ClipNone); 215 InitPixelShader(sNV12ClipShader, mNV12Shader, ClipType::RoundedRect); 216 return mContinueInit; 217 } 218 219 void DeviceAttachmentsD3D11::InitVertexShader(const ShaderBytes& aShader, 220 ID3D11VertexShader** aOut) { 221 if (!mContinueInit) { 222 return; 223 } 224 if (Failed(mDevice->CreateVertexShader(aShader.mData, aShader.mLength, 225 nullptr, aOut), 226 "create vs")) { 227 mContinueInit = false; 228 } 229 } 230 231 void DeviceAttachmentsD3D11::InitPixelShader(const ShaderBytes& aShader, 232 ID3D11PixelShader** aOut) { 233 if (!mContinueInit) { 234 return; 235 } 236 if (Failed(mDevice->CreatePixelShader(aShader.mData, aShader.mLength, nullptr, 237 aOut), 238 "create ps")) { 239 mContinueInit = false; 240 } 241 } 242 243 bool DeviceAttachmentsD3D11::Failed(HRESULT hr, const char* aContext) { 244 if (SUCCEEDED(hr)) { 245 return false; 246 } 247 248 gfxCriticalNote << "[D3D11] " << aContext << " failed: " << hexa(hr); 249 return true; 250 } 251 252 } // namespace layers 253 } // namespace mozilla