D3D11BlendStateObject::D3D11BlendStateObject(BlendStateDesc const & desc) : BlendStateObject(desc) { D3D11RenderEngine& re = *checked_cast<D3D11RenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); RenderDeviceCaps const & caps = re.DeviceCaps(); D3D11_BLEND_DESC d3d_desc; d3d_desc.AlphaToCoverageEnable = desc.alpha_to_coverage_enable; d3d_desc.IndependentBlendEnable = caps.independent_blend_support ? desc.independent_blend_enable : false; for (int i = 0; i < 8; ++ i) { uint32_t const rt_index = caps.independent_blend_support ? i : 0; d3d_desc.RenderTarget[i].BlendEnable = desc.blend_enable[rt_index]; d3d_desc.RenderTarget[i].SrcBlend = D3D11Mapping::Mapping(desc.src_blend[rt_index]); d3d_desc.RenderTarget[i].DestBlend = D3D11Mapping::Mapping(desc.dest_blend[rt_index]); d3d_desc.RenderTarget[i].BlendOp = D3D11Mapping::Mapping(desc.blend_op[rt_index]); d3d_desc.RenderTarget[i].SrcBlendAlpha = D3D11Mapping::Mapping(desc.src_blend_alpha[rt_index]); d3d_desc.RenderTarget[i].DestBlendAlpha = D3D11Mapping::Mapping(desc.dest_blend_alpha[rt_index]); d3d_desc.RenderTarget[i].BlendOpAlpha = D3D11Mapping::Mapping(desc.blend_op_alpha[rt_index]); d3d_desc.RenderTarget[i].RenderTargetWriteMask = static_cast<UINT8>(D3D11Mapping::MappingColorMask(desc.color_write_mask[rt_index])); } ID3D11Device* d3d_device = re.D3DDevice().get(); if (re.D3D11RuntimeSubVer() >= 1) { ID3D11Device1* d3d_device_1 = static_cast<ID3D11Device1*>(d3d_device); D3D11_BLEND_DESC1 d3d_desc1; d3d_desc1.AlphaToCoverageEnable = d3d_desc.AlphaToCoverageEnable; d3d_desc1.IndependentBlendEnable = d3d_desc.IndependentBlendEnable; for (int i = 0; i < 8; ++ i) { uint32_t const rt_index = caps.independent_blend_support ? i : 0; d3d_desc1.RenderTarget[i].BlendEnable = d3d_desc.RenderTarget[i].BlendEnable; d3d_desc1.RenderTarget[i].LogicOpEnable = desc.logic_op_enable[i]; d3d_desc1.RenderTarget[i].SrcBlend = d3d_desc.RenderTarget[i].SrcBlend; d3d_desc1.RenderTarget[i].DestBlend = d3d_desc.RenderTarget[i].DestBlend; d3d_desc1.RenderTarget[i].BlendOp = d3d_desc.RenderTarget[i].BlendOp; d3d_desc1.RenderTarget[i].SrcBlendAlpha = d3d_desc.RenderTarget[i].SrcBlendAlpha; d3d_desc1.RenderTarget[i].DestBlendAlpha = d3d_desc.RenderTarget[i].DestBlendAlpha; d3d_desc1.RenderTarget[i].BlendOpAlpha = d3d_desc.RenderTarget[i].BlendOpAlpha; d3d_desc1.RenderTarget[i].LogicOp = caps.logic_op_support ? D3D11Mapping::Mapping(desc.logic_op[rt_index]) : D3D11_LOGIC_OP_NOOP; d3d_desc1.RenderTarget[i].RenderTargetWriteMask = d3d_desc.RenderTarget[i].RenderTargetWriteMask; } ID3D11BlendState1* blend_state; TIF(d3d_device_1->CreateBlendState1(&d3d_desc1, &blend_state)); blend_state_ = MakeCOMPtr(blend_state); } else { ID3D11BlendState* blend_state; TIF(d3d_device->CreateBlendState(&d3d_desc, &blend_state)); blend_state_ = MakeCOMPtr(blend_state); } }
TexturePtr DShowVMR9Allocator::PresentTexture() { unique_lock<mutex> lock(mutex_); if (FAILED(d3d_device_->TestCooperativeLevel())) { return TexturePtr(); } if (cur_surf_index_ < surfaces_.size()) { TIF(d3d_device_->GetRenderTargetData(surfaces_[cur_surf_index_], cache_surf_.get())); D3DLOCKED_RECT d3dlocked_rc; TIF(cache_surf_->LockRect(&d3dlocked_rc, nullptr, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)); uint32_t const width = present_tex_->Width(0); uint32_t const height = present_tex_->Height(0); uint32_t const texel_size = NumFormatBytes(present_tex_->Format()); uint8_t const * src = static_cast<uint8_t const *>(d3dlocked_rc.pBits); { ElementFormat fmt = present_tex_->Format(); Texture::Mapper mapper(*present_tex_, 0, 0, TMA_Write_Only, 0, 0, width, height); uint8_t* dst = mapper.Pointer<uint8_t>(); if ((EF_ARGB8 == fmt) || (EF_ARGB8_SRGB == fmt)) { for (uint32_t y = 0; y < height; ++ y) { std::memcpy(dst, src, width * texel_size); dst += mapper.RowPitch(); src += d3dlocked_rc.Pitch; } } else { BOOST_ASSERT((EF_ABGR8 == fmt) || (EF_ABGR8_SRGB == fmt)); for (uint32_t y = 0; y < height; ++ y) { for (uint32_t x = 0; x < width; ++ x) { dst[x * 4 + 0] = src[x * 4 + 2]; dst[x * 4 + 1] = src[x * 4 + 1]; dst[x * 4 + 2] = src[x * 4 + 0]; dst[x * 4 + 3] = src[x * 4 + 3]; } dst += mapper.RowPitch(); src += d3dlocked_rc.Pitch; } } } TIF(cache_surf_->UnlockRect()); } return present_tex_; }
// 构造函数 ///////////////////////////////////////////////////////////////////////////////// DSAudioEngine::DSAudioEngine() { mod_dsound_ = ::LoadLibraryEx(TEXT("dsound.dll"), nullptr, 0); if (nullptr == mod_dsound_) { ::MessageBoxW(nullptr, L"Can't load dsound.dll", L"Error", MB_OK); } if (mod_dsound_ != nullptr) { DynamicDirectSoundCreate_ = reinterpret_cast<DirectSoundCreateFunc>(::GetProcAddress(mod_dsound_, "DirectSoundCreate")); } IDirectSound* dsound(nullptr); TIF(DynamicDirectSoundCreate_(&DSDEVID_DefaultPlayback, &dsound, nullptr)); dsound_ = MakeCOMPtr(dsound); TIF(dsound_->SetCooperativeLevel(::GetForegroundWindow(), DSSCL_PRIORITY)); DSBUFFERDESC desc; std::memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER; IDirectSoundBuffer* pDSBPrimary(nullptr); TIF(dsound_->CreateSoundBuffer(&desc, &pDSBPrimary, nullptr)); WAVEFORMATEX wfx; std::memset(&wfx, 0, sizeof(wfx)); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; wfx.nSamplesPerSec = 22050; wfx.wBitsPerSample = 16; wfx.nBlockAlign = wfx.wBitsPerSample * wfx.nChannels / 8; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; TIF(pDSBPrimary->SetFormat(&wfx)); IDirectSound3DListener* ds3dListener; TIF(pDSBPrimary->QueryInterface(IID_IDirectSound3DListener, reinterpret_cast<void**>(&ds3dListener))); ds3dListener_ = MakeCOMPtr(ds3dListener); this->SetListenerPos(float3(0, 0, 0)); this->SetListenerVel(float3(0, 0, 0)); this->SetListenerOri(float3(0, 0, 1), float3(0, 1, 0)); pDSBPrimary->Release(); }
// 缓冲区复位以便于从头播放 ///////////////////////////////////////////////////////////////////////////////// void DSMusicBuffer::DoReset() { this->writePos_ = 0; dataSource_->Reset(); // 锁定缓冲区 uint8_t* lockedBuffer; // 指向缓冲区锁定的内存的指针 DWORD lockedBufferSize; // 锁定的内存大小 TIF(buffer_->Lock(0, fillSize_ * fillCount_, reinterpret_cast<void**>(&lockedBuffer), &lockedBufferSize, nullptr, nullptr, 0)); std::vector<uint8_t> data(fillSize_ * fillCount_); data.resize(dataSource_->Read(&data[0], fillSize_ * fillCount_)); if (data.empty()) { // 如果音频数据空白,用静音填充 std::fill_n(lockedBuffer, lockedBufferSize, 0); } else { // 如果数据源比缓冲区小,则用音频数据填充缓冲区 std::copy(data.begin(), data.end(), lockedBuffer); // 剩下的区域用空白填充 std::fill_n(lockedBuffer + data.size(), lockedBufferSize - data.size(), 0); } // 缓冲区解锁 buffer_->Unlock(lockedBuffer, lockedBufferSize, nullptr, 0); buffer_->SetCurrentPosition(0); }
void DShowVMR9Allocator::CreateDevice() { memset(&d3dpp_, 0, sizeof(d3dpp_)); d3dpp_.Windowed = true; d3dpp_.hDeviceWindow = wnd_; d3dpp_.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp_.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; D3DCAPS9 caps; d3d_->GetDeviceCaps(0, D3DDEVTYPE_HAL, &caps); uint32_t vp_mode; if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) { vp_mode = D3DCREATE_HARDWARE_VERTEXPROCESSING; if ((caps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0) { vp_mode |= D3DCREATE_PUREDEVICE; } } else { vp_mode = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } IDirect3DDevice9* d3d_device; TIF(d3d_->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd_, vp_mode | D3DCREATE_FPU_PRESERVE | D3DCREATE_MULTITHREADED, &d3dpp_, &d3d_device)); d3d_device_ = MakeCOMPtr(d3d_device); }
void D3D11RenderWindow::SwapBuffers() { if (swap_chain_) { TIF(swap_chain_->Present(sync_interval_, 0)); #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) if (dxgi_sub_ver_ >= 2) { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); D3D11RenderEngine& d3d11_re = *checked_cast<D3D11RenderEngine*>(&rf.RenderEngineInstance()); ID3D11DeviceContextPtr d3d_imm_ctx = d3d11_re.D3DDeviceImmContext(); ID3D11DeviceContext1Ptr const & d3d_imm_ctx_1 = static_pointer_cast<ID3D11DeviceContext1>(d3d_imm_ctx); d3d_imm_ctx_1->DiscardView(render_target_view_.get()); if (depth_stencil_view_) { d3d_imm_ctx_1->DiscardView(depth_stencil_view_.get()); } if (render_target_view_right_eye_) { d3d_imm_ctx_1->DiscardView(render_target_view_right_eye_.get()); } if (depth_stencil_view_right_eye_) { d3d_imm_ctx_1->DiscardView(depth_stencil_view_right_eye_.get()); } } #endif } }
D3D11DepthStencilStateObject::D3D11DepthStencilStateObject(DepthStencilStateDesc const & desc) : DepthStencilStateObject(desc) { D3D11_DEPTH_STENCIL_DESC d3d_desc; d3d_desc.DepthEnable = desc.depth_enable; d3d_desc.DepthWriteMask = D3D11Mapping::Mapping(desc.depth_write_mask); d3d_desc.DepthFunc = D3D11Mapping::Mapping(desc.depth_func); d3d_desc.StencilEnable = desc.front_stencil_enable; d3d_desc.StencilReadMask = static_cast<uint8_t>(desc.front_stencil_read_mask); d3d_desc.StencilWriteMask = static_cast<uint8_t>(desc.front_stencil_write_mask); d3d_desc.FrontFace.StencilFailOp = D3D11Mapping::Mapping(desc.front_stencil_fail); d3d_desc.FrontFace.StencilDepthFailOp = D3D11Mapping::Mapping(desc.front_stencil_depth_fail); d3d_desc.FrontFace.StencilPassOp = D3D11Mapping::Mapping(desc.front_stencil_pass); d3d_desc.FrontFace.StencilFunc = D3D11Mapping::Mapping(desc.front_stencil_func); d3d_desc.BackFace.StencilFailOp = D3D11Mapping::Mapping(desc.back_stencil_fail); d3d_desc.BackFace.StencilDepthFailOp = D3D11Mapping::Mapping(desc.back_stencil_depth_fail); d3d_desc.BackFace.StencilPassOp = D3D11Mapping::Mapping(desc.back_stencil_pass); d3d_desc.BackFace.StencilFunc = D3D11Mapping::Mapping(desc.back_stencil_func); ID3D11Device* d3d_device = checked_cast<D3D11RenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance())->D3DDevice().get(); ID3D11DepthStencilState* ds_state; TIF(d3d_device->CreateDepthStencilState(&d3d_desc, &ds_state)); depth_stencil_state_ = MakeCOMPtr(ds_state); }
D3D11RasterizerStateObject::D3D11RasterizerStateObject(RasterizerStateDesc const & desc) : RasterizerStateObject(desc) { D3D11RenderEngine& re = *checked_cast<D3D11RenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); ID3D11Device* d3d_device = re.D3DDevice().get(); D3D11_RASTERIZER_DESC d3d_desc; d3d_desc.FillMode = D3D11Mapping::Mapping(desc.polygon_mode); d3d_desc.CullMode = D3D11Mapping::Mapping(desc.cull_mode); d3d_desc.FrontCounterClockwise = desc.front_face_ccw; d3d_desc.DepthBias = static_cast<int>(desc.polygon_offset_units); d3d_desc.DepthBiasClamp = desc.polygon_offset_units; d3d_desc.SlopeScaledDepthBias = desc.polygon_offset_factor; d3d_desc.DepthClipEnable = re.DeviceFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 ? desc.depth_clip_enable : true; d3d_desc.ScissorEnable = desc.scissor_enable; d3d_desc.MultisampleEnable = desc.multisample_enable; d3d_desc.AntialiasedLineEnable = false; if (re.D3D11RuntimeSubVer() >= 1) { ID3D11Device1* d3d_device_1 = static_cast<ID3D11Device1*>(d3d_device); D3D11_RASTERIZER_DESC1 d3d_desc1; d3d_desc1.FillMode = d3d_desc.FillMode; d3d_desc1.CullMode = d3d_desc.CullMode; d3d_desc1.FrontCounterClockwise = d3d_desc.FrontCounterClockwise; d3d_desc1.DepthBias = d3d_desc.DepthBias; d3d_desc1.DepthBiasClamp = d3d_desc.DepthBiasClamp; d3d_desc1.SlopeScaledDepthBias = d3d_desc.SlopeScaledDepthBias; d3d_desc1.DepthClipEnable = d3d_desc.DepthClipEnable; d3d_desc1.ScissorEnable = d3d_desc.ScissorEnable; d3d_desc1.MultisampleEnable = d3d_desc.MultisampleEnable; d3d_desc1.AntialiasedLineEnable = d3d_desc.AntialiasedLineEnable; d3d_desc1.ForcedSampleCount = 0; ID3D11RasterizerState1* rasterizer_state; TIF(d3d_device_1->CreateRasterizerState1(&d3d_desc1, &rasterizer_state)); rasterizer_state_ = MakeCOMPtr(rasterizer_state); } else { ID3D11RasterizerState* rasterizer_state; TIF(d3d_device->CreateRasterizerState(&d3d_desc, &rasterizer_state)); rasterizer_state_ = MakeCOMPtr(rasterizer_state); } }
void D3D11TextureCube::MapCube(uint32_t array_index, CubeFaces face, uint32_t level, TextureMapAccess tma, uint32_t x_offset, uint32_t y_offset, uint32_t /*width*/, uint32_t /*height*/, void*& data, uint32_t& row_pitch) { D3D11_MAPPED_SUBRESOURCE mapped; TIF(d3d_imm_ctx_->Map(d3dTextureCube_.get(), D3D11CalcSubresource(level, array_index * 6 + face - CF_Positive_X, num_mip_maps_), D3D11Mapping::Mapping(tma, type_, access_hint_, num_mip_maps_), 0, &mapped)); uint8_t* p = static_cast<uint8_t*>(mapped.pData); data = p + y_offset * mapped.RowPitch + x_offset * NumFormatBytes(format_); row_pitch = mapped.RowPitch; }
HRESULT DShowVMR9Allocator::PresentImage(DWORD_PTR dwUserID, VMR9PresentationInfo* lpPresInfo) { if (dwUserID != USER_ID) { return S_OK; } // parameter validation if (nullptr == lpPresInfo) { return E_POINTER; } else { if (nullptr == lpPresInfo->lpSurf) { return E_POINTER; } } unique_lock<mutex> lock(mutex_); cur_surf_index_ = 0xFFFFFFFF; for (uint32_t i = 0; i < surfaces_.size(); ++ i) { if (surfaces_[i] == lpPresInfo->lpSurf) { cur_surf_index_ = i; break; } } if (D3DERR_DEVICENOTRESET == d3d_device_->TestCooperativeLevel()) { cache_surf_.reset(); for (size_t i = 0; i < surfaces_.size(); ++ i) { if (surfaces_[i] != nullptr) { surfaces_[i]->Release(); surfaces_[i] = nullptr; } } this->CreateDevice(); HMONITOR hMonitor = d3d_->GetAdapterMonitor(D3DADAPTER_DEFAULT); TIF(vmr_surf_alloc_notify_->ChangeD3DDevice(d3d_device_.get(), hMonitor)); } return S_OK; }
void D3D11Texture3D::Map3D(uint32_t array_index, uint32_t level, TextureMapAccess tma, uint32_t x_offset, uint32_t y_offset, uint32_t z_offset, uint32_t /*width*/, uint32_t /*height*/, uint32_t /*depth*/, void*& data, uint32_t& row_pitch, uint32_t& slice_pitch) { D3D11_MAPPED_SUBRESOURCE mapped; TIF(d3d_imm_ctx_->Map(d3dTexture3D_.get(), D3D11CalcSubresource(level, array_index, num_mip_maps_), D3D11Mapping::Mapping(tma, type_, access_hint_, num_mip_maps_), 0, &mapped)); uint8_t* p = static_cast<uint8_t*>(mapped.pData); data = p + z_offset * mapped.DepthPitch + y_offset * mapped.RowPitch + x_offset * NumFormatBytes(format_); row_pitch = mapped.RowPitch; slice_pitch = mapped.DepthPitch; }
HRESULT DShowVMR9Allocator::AdviseNotify(IVMRSurfaceAllocatorNotify9* lpIVMRSurfAllocNotify) { unique_lock<mutex> lock(mutex_); vmr_surf_alloc_notify_ = MakeCOMPtr(lpIVMRSurfAllocNotify); vmr_surf_alloc_notify_->AddRef(); HMONITOR hMonitor = d3d_->GetAdapterMonitor(D3DADAPTER_DEFAULT); TIF(vmr_surf_alloc_notify_->SetD3DDevice(d3d_device_.get(), hMonitor)); return S_OK; }
void DSMusicBuffer::LoopUpdateBuffer() { unique_lock<mutex> lock(play_mutex_); while (!played_) { play_cond_.wait(lock); } played_ = false; while (!stopped_) { // 锁定缓冲区 uint8_t* lockedBuffer; // 指向缓冲区锁定的内存的指针 DWORD lockedBufferSize; // 锁定的内存大小 TIF(buffer_->Lock(fillSize_ * writePos_, fillSize_, reinterpret_cast<void**>(&lockedBuffer), &lockedBufferSize, nullptr, nullptr, 0)); std::vector<uint8_t> data(fillSize_); data.resize(dataSource_->Read(&data[0], fillSize_)); if (data.empty()) { if (loop_) { stopped_ = false; this->Reset(); } else { stopped_ = true; } } else { std::copy(data.begin(), data.end(), lockedBuffer); std::fill_n(lockedBuffer + data.size(), lockedBufferSize - data.size(), 0); } // 缓冲区解锁 buffer_->Unlock(lockedBuffer, lockedBufferSize, nullptr, 0); // 形成环形缓冲区 ++ writePos_; writePos_ %= fillCount_; Sleep(1000 / PreSecond); } }
D3D11SamplerStateObject::D3D11SamplerStateObject(SamplerStateDesc const & desc) : SamplerStateObject(desc) { D3D11RenderEngine const & render_eng = *checked_cast<D3D11RenderEngine const *>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); ID3D11Device* d3d_device = render_eng.D3DDevice().get(); D3D_FEATURE_LEVEL feature_level = render_eng.DeviceFeatureLevel(); D3D11_SAMPLER_DESC d3d_desc; d3d_desc.Filter = D3D11Mapping::Mapping(desc.filter); TexAddressingMode addr_mode_u = desc.addr_mode_u; if ((feature_level <= D3D_FEATURE_LEVEL_9_2) && (TAM_Border == desc.addr_mode_u)) { addr_mode_u = TAM_Clamp; } d3d_desc.AddressU = D3D11Mapping::Mapping(addr_mode_u); TexAddressingMode addr_mode_v = desc.addr_mode_v; if ((feature_level <= D3D_FEATURE_LEVEL_9_2) && (TAM_Border == desc.addr_mode_u)) { addr_mode_v = TAM_Clamp; } d3d_desc.AddressV = D3D11Mapping::Mapping(addr_mode_v); TexAddressingMode addr_mode_w = desc.addr_mode_w; if ((feature_level <= D3D_FEATURE_LEVEL_9_2) && (TAM_Border == desc.addr_mode_u)) { addr_mode_w = TAM_Clamp; } d3d_desc.AddressW = D3D11Mapping::Mapping(addr_mode_w); d3d_desc.MipLODBias = desc.mip_map_lod_bias; d3d_desc.MaxAnisotropy = (feature_level <= D3D_FEATURE_LEVEL_9_1) ? 1 : desc.max_anisotropy; d3d_desc.ComparisonFunc = D3D11Mapping::Mapping(desc.cmp_func); d3d_desc.BorderColor[0] = desc.border_clr.r(); d3d_desc.BorderColor[1] = desc.border_clr.g(); d3d_desc.BorderColor[2] = desc.border_clr.b(); d3d_desc.BorderColor[3] = desc.border_clr.a(); if (feature_level <= D3D_FEATURE_LEVEL_9_3) { d3d_desc.MinLOD = floor(desc.min_lod); d3d_desc.MaxLOD = std::numeric_limits<float>::max(); } else { d3d_desc.MinLOD = desc.min_lod; d3d_desc.MaxLOD = desc.max_lod; } ID3D11SamplerState* sampler_state; TIF(d3d_device->CreateSamplerState(&d3d_desc, &sampler_state)); sampler_state_ = MakeCOMPtr(sampler_state); }
// 构造函数。建立一个可以用于流式播放的缓冲区 ///////////////////////////////////////////////////////////////////////////////// DSMusicBuffer::DSMusicBuffer(AudioDataSourcePtr const & dataSource, uint32_t bufferSeconds, float volume) : MusicBuffer(dataSource), writePos_(0), played_(false), stopped_(true) { WAVEFORMATEX wfx(WaveFormatEx(dataSource)); fillSize_ = wfx.nAvgBytesPerSec / PreSecond; fillCount_ = bufferSeconds * PreSecond; bool const mono(1 == wfx.nChannels); shared_ptr<IDirectSound> const & dsound = checked_cast<DSAudioEngine const *>(&Context::Instance().AudioFactoryInstance().AudioEngineInstance())->DSound(); // 建立 DirectSound 缓冲区,要尽量减少使用建立标志, // 因为使用太多不必要的标志会影响硬件加速性能 DSBUFFERDESC dsbd; std::memset(&dsbd, 0, sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = DSBCAPS_CTRLVOLUME; if (mono) { dsbd.dwFlags |= DSBCAPS_CTRL3D | DSBCAPS_MUTE3DATMAXDISTANCE; dsbd.guid3DAlgorithm = GUID_NULL; } dsbd.dwBufferBytes = fillSize_ * fillCount_; dsbd.lpwfxFormat = &wfx; // DirectSound只能播放PCM数据。其他格式可能不能工作。 IDirectSoundBuffer* buffer; TIF(dsound->CreateSoundBuffer(&dsbd, &buffer, nullptr)); buffer_ = MakeCOMPtr(buffer); if (mono) { IDirectSound3DBuffer* ds3DBuffer; buffer_->QueryInterface(IID_IDirectSound3DBuffer, reinterpret_cast<void**>(&ds3DBuffer)); ds3DBuffer_ = MakeCOMPtr(ds3DBuffer); } this->Position(float3::Zero()); this->Velocity(float3::Zero()); this->Direction(float3::Zero()); this->Volume(volume); this->Reset(); }
void Extract7z(ResIdentifierPtr const & archive_is, std::string const & password, std::string const & extract_file_path, std::shared_ptr<std::ostream> const & os) { std::shared_ptr<IInArchive> archive; uint32_t real_index; GetArchiveIndex(archive, real_index, archive_is, password, extract_file_path); if (real_index != 0xFFFFFFFF) { std::shared_ptr<ISequentialOutStream> out_stream = MakeCOMPtr(new COutStream); checked_pointer_cast<COutStream>(out_stream)->Attach(os); std::shared_ptr<IArchiveExtractCallback> ecb = MakeCOMPtr(new CArchiveExtractCallback); checked_pointer_cast<CArchiveExtractCallback>(ecb)->Init(password, out_stream); TIF(archive->Extract(&real_index, 1, false, ecb.get())); } }
void* D3D11GraphicsBuffer::Map(BufferAccess ba) { BOOST_ASSERT(buffer_); D3D11_MAP type; switch (ba) { case BA_Read_Only: type = D3D11_MAP_READ; break; case BA_Write_Only: if ((EAH_CPU_Write == access_hint_) || ((EAH_CPU_Write | EAH_GPU_Read) == access_hint_)) { type = D3D11_MAP_WRITE_DISCARD; } else { type = D3D11_MAP_WRITE; } break; case BA_Read_Write: type = D3D11_MAP_READ_WRITE; break; case BA_Write_No_Overwrite: type = D3D11_MAP_WRITE_NO_OVERWRITE; break; default: BOOST_ASSERT(false); type = D3D11_MAP_READ; break; } D3D11_MAPPED_SUBRESOURCE mapped; TIF(d3d_imm_ctx_->Map(buffer_.get(), 0, type, 0, &mapped)); return mapped.pData; }
D3D11Texture3D::D3D11Texture3D(uint32_t width, uint32_t height, uint32_t depth, uint32_t numMipMaps, uint32_t array_size, ElementFormat format, uint32_t sample_count, uint32_t sample_quality, uint32_t access_hint, ElementInitData const * init_data) : D3D11Texture(TT_3D, sample_count, sample_quality, access_hint) { BOOST_ASSERT(1 == array_size); if (0 == numMipMaps) { num_mip_maps_ = 1; uint32_t w = width; uint32_t h = height; uint32_t d = depth; while ((w != 1) || (h != 1) || (d != 1)) { ++ num_mip_maps_; w = std::max<uint32_t>(1U, w / 2); h = std::max<uint32_t>(1U, h / 2); d = std::max<uint32_t>(1U, d / 2); } } else { num_mip_maps_ = numMipMaps; } D3D11RenderEngine const & re = *checked_cast<D3D11RenderEngine const *>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); if (re.DeviceFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) { if ((num_mip_maps_ > 1) && (((width & (width - 1)) != 0) || ((height & (height - 1)) != 0) || ((depth & (depth - 1)) != 0))) { // height or width is not a power of 2 and multiple mip levels are specified. This is not supported at feature levels below 10.0. num_mip_maps_ = 1; } } array_size_ = array_size; format_ = format; widths_.assign(1, width); heights_.assign(1, height); depthes_.assign(1, depth); desc_.Width = width; desc_.Height = height; desc_.Depth = depth; desc_.MipLevels = num_mip_maps_; desc_.Format = D3D11Mapping::MappingFormat(format_); this->GetD3DFlags(desc_.Usage, desc_.BindFlags, desc_.CPUAccessFlags, desc_.MiscFlags); std::vector<D3D11_SUBRESOURCE_DATA> subres_data(num_mip_maps_); if (init_data != nullptr) { for (uint32_t i = 0; i < num_mip_maps_; ++ i) { subres_data[i].pSysMem = init_data[i].data; subres_data[i].SysMemPitch = init_data[i].row_pitch; subres_data[i].SysMemSlicePitch = init_data[i].slice_pitch; } } ID3D11Texture3D* d3d_tex; TIF(d3d_device_->CreateTexture3D(&desc_, (init_data != nullptr) ? &subres_data[0] : nullptr, &d3d_tex)); d3dTexture3D_ = MakeCOMPtr(d3d_tex); this->UpdateParams(); if ((access_hint & (EAH_GPU_Read | EAH_Generate_Mips)) && (num_mip_maps_ > 1)) { this->RetriveD3DShaderResourceView(0, array_size_, 0, num_mip_maps_); } }
void D3D11GraphicsBuffer::CreateBuffer(D3D11_SUBRESOURCE_DATA const * subres_init) { D3D11_BUFFER_DESC desc; this->GetD3DFlags(desc.Usage, desc.CPUAccessFlags, desc.BindFlags, desc.MiscFlags); desc.ByteWidth = size_in_byte_; desc.StructureByteStride = NumFormatBytes(fmt_as_shader_res_); ID3D11Buffer* buffer; TIF(d3d_device_->CreateBuffer(&desc, subres_init, &buffer)); buffer_ = MakeCOMPtr(buffer); if ((access_hint_ & EAH_GPU_Read) && (fmt_as_shader_res_ != EF_Unknown)) { D3D11_SHADER_RESOURCE_VIEW_DESC sr_desc; sr_desc.Format = (access_hint_ & EAH_GPU_Structured) ? DXGI_FORMAT_UNKNOWN : D3D11Mapping::MappingFormat(fmt_as_shader_res_); sr_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; sr_desc.Buffer.ElementOffset = 0; sr_desc.Buffer.ElementWidth = size_in_byte_ / desc.StructureByteStride; ID3D11ShaderResourceView* d3d_sr_view; TIF(d3d_device_->CreateShaderResourceView(buffer_.get(), &sr_desc, &d3d_sr_view)); d3d_sr_view_ = MakeCOMPtr(d3d_sr_view); } if ((access_hint_ & EAH_GPU_Unordered) && (fmt_as_shader_res_ != EF_Unknown)) { D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc; if (access_hint_ & EAH_Raw) { uav_desc.Format = DXGI_FORMAT_R32_TYPELESS; } else if (access_hint_ & EAH_GPU_Structured) { uav_desc.Format = DXGI_FORMAT_UNKNOWN; } else { uav_desc.Format = D3D11Mapping::MappingFormat(fmt_as_shader_res_); } uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; uav_desc.Buffer.FirstElement = 0; uav_desc.Buffer.NumElements = size_in_byte_ / desc.StructureByteStride; uav_desc.Buffer.Flags = 0; if (access_hint_ & EAH_Raw) { uav_desc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_RAW; } if (access_hint_ & EAH_Append) { uav_desc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_APPEND; } if (access_hint_ & EAH_Counter) { uav_desc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_COUNTER; } ID3D11UnorderedAccessView* d3d_ua_view; TIF(d3d_device_->CreateUnorderedAccessView(buffer_.get(), &uav_desc, &d3d_ua_view)); d3d_ua_view_ = MakeCOMPtr(d3d_ua_view); } }
void D3D11RenderWindow::UpdateSurfacesPtrs() { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); D3D11RenderEngine& d3d11_re = *checked_cast<D3D11RenderEngine*>(&rf.RenderEngineInstance()); ID3D11DevicePtr d3d_device = d3d11_re.D3DDevice(); // Create a render target view ID3D11Texture2D* back_buffer; TIF(swap_chain_->GetBuffer(0, IID_ID3D11Texture2D, reinterpret_cast<void**>(&back_buffer))); back_buffer_ = MakeCOMPtr(back_buffer); D3D11_TEXTURE2D_DESC bb_desc; back_buffer_->GetDesc(&bb_desc); D3D11_RENDER_TARGET_VIEW_DESC rtv_desc; rtv_desc.Format = bb_desc.Format; #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) if (dxgi_sub_ver_ >= 2) { if (bb_desc.SampleDesc.Count > 1) { rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; rtv_desc.Texture2DMSArray.FirstArraySlice = 0; rtv_desc.Texture2DMSArray.ArraySize = 1; } else { rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtv_desc.Texture2DArray.MipSlice = 0; rtv_desc.Texture2DArray.FirstArraySlice = 0; rtv_desc.Texture2DArray.ArraySize = 1; } } else #endif { if (bb_desc.SampleDesc.Count > 1) { rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; } else { rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtv_desc.Texture2D.MipSlice = 0; } } ID3D11RenderTargetView* render_target_view; TIF(d3d_device->CreateRenderTargetView(back_buffer_.get(), &rtv_desc, &render_target_view)); render_target_view_ = MakeCOMPtr(render_target_view); #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) bool stereo = (STM_LCDShutter == Context::Instance().Config().graphics_cfg.stereo_method) && dxgi_stereo_support_; if (stereo) { if (bb_desc.SampleDesc.Count > 1) { rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; rtv_desc.Texture2DMSArray.FirstArraySlice = 1; rtv_desc.Texture2DMSArray.ArraySize = 1; } else { rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtv_desc.Texture2DArray.MipSlice = 0; rtv_desc.Texture2DArray.FirstArraySlice = 1; rtv_desc.Texture2DArray.ArraySize = 1; } TIF(d3d_device->CreateRenderTargetView(back_buffer_.get(), &rtv_desc, &render_target_view)); render_target_view_right_eye_ = MakeCOMPtr(render_target_view); } #else bool stereo = false; #endif if (depth_stencil_format_ != DXGI_FORMAT_UNKNOWN) { // Create depth stencil texture D3D11_TEXTURE2D_DESC ds_desc; ds_desc.Width = this->Width(); ds_desc.Height = this->Height(); ds_desc.MipLevels = 1; ds_desc.ArraySize = stereo ? 2 : 1; ds_desc.Format = depth_stencil_format_; ds_desc.SampleDesc.Count = bb_desc.SampleDesc.Count; ds_desc.SampleDesc.Quality = bb_desc.SampleDesc.Quality; ds_desc.Usage = D3D11_USAGE_DEFAULT; ds_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; ds_desc.CPUAccessFlags = 0; ds_desc.MiscFlags = 0; ID3D11Texture2D* depth_stencil; TIF(d3d_device->CreateTexture2D(&ds_desc, nullptr, &depth_stencil)); depth_stencil_ = MakeCOMPtr(depth_stencil); // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC dsv_desc; dsv_desc.Format = depth_stencil_format_; dsv_desc.Flags = 0; #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) if (dxgi_sub_ver_ >= 2) { if (bb_desc.SampleDesc.Count > 1) { dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; dsv_desc.Texture2DMSArray.FirstArraySlice = 0; dsv_desc.Texture2DMSArray.ArraySize = 1; } else { dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; dsv_desc.Texture2DArray.MipSlice = 0; dsv_desc.Texture2DArray.FirstArraySlice = 0; dsv_desc.Texture2DArray.ArraySize = 1; } } else #endif { if (bb_desc.SampleDesc.Count > 1) { dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; } else { dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; dsv_desc.Texture2D.MipSlice = 0; } } ID3D11DepthStencilView* depth_stencil_view; TIF(d3d_device->CreateDepthStencilView(depth_stencil_.get(), &dsv_desc, &depth_stencil_view)); depth_stencil_view_ = MakeCOMPtr(depth_stencil_view); #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) if (stereo) { if (bb_desc.SampleDesc.Count > 1) { dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; dsv_desc.Texture2DMSArray.FirstArraySlice = 1; dsv_desc.Texture2DMSArray.ArraySize = 1; } else { dsv_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; dsv_desc.Texture2DArray.MipSlice = 0; dsv_desc.Texture2DArray.FirstArraySlice = 1; dsv_desc.Texture2DArray.ArraySize = 1; } TIF(d3d_device->CreateDepthStencilView(depth_stencil_.get(), &dsv_desc, &depth_stencil_view)); depth_stencil_view_right_eye_ = MakeCOMPtr(depth_stencil_view); } #endif } if (!!stereo_amd_qb_ext_) { stereo_amd_right_eye_height_ = stereo_amd_qb_ext_->GetLineOffset(swap_chain_.get()); } this->Attach(ATT_Color0, MakeSharedPtr<D3D11RenderTargetRenderView>(render_target_view_, this->Width(), this->Height(), D3D11Mapping::MappingFormat(back_buffer_format_))); if (depth_stencil_view_) { this->Attach(ATT_DepthStencil, MakeSharedPtr<D3D11DepthStencilRenderView>(depth_stencil_view_, this->Width(), this->Height(), D3D11Mapping::MappingFormat(depth_stencil_format_))); } }
D3D11TextureCube::D3D11TextureCube(uint32_t size, uint32_t numMipMaps, uint32_t array_size, ElementFormat format, uint32_t sample_count, uint32_t sample_quality, uint32_t access_hint, ElementInitData const * init_data) : D3D11Texture(TT_Cube, sample_count, sample_quality, access_hint) { if (0 == numMipMaps) { num_mip_maps_ = 1; uint32_t w = size; while (w != 1) { ++ num_mip_maps_; w = std::max<uint32_t>(1U, w / 2); } } else { num_mip_maps_ = numMipMaps; } D3D11RenderEngine const & re = *checked_cast<D3D11RenderEngine const *>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); if (re.DeviceFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) { if ((num_mip_maps_ > 1) && ((size & (size - 1)) != 0)) { // height or width is not a power of 2 and multiple mip levels are specified. This is not supported at feature levels below 10.0. num_mip_maps_ = 1; } } array_size_ = array_size; format_ = format; widths_.assign(1, size); desc_.Width = size; desc_.Height = size; desc_.MipLevels = num_mip_maps_; desc_.ArraySize = 6 * array_size_; desc_.Format = D3D11Mapping::MappingFormat(format_); desc_.SampleDesc.Count = 1; desc_.SampleDesc.Quality = 0; this->GetD3DFlags(desc_.Usage, desc_.BindFlags, desc_.CPUAccessFlags, desc_.MiscFlags); desc_.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; std::vector<D3D11_SUBRESOURCE_DATA> subres_data(6 * num_mip_maps_); if (init_data != nullptr) { for (int face = 0; face < 6; ++ face) { for (uint32_t i = 0; i < num_mip_maps_; ++ i) { subres_data[face * num_mip_maps_ + i].pSysMem = init_data[face * num_mip_maps_ + i].data; subres_data[face * num_mip_maps_ + i].SysMemPitch = init_data[face * num_mip_maps_ + i].row_pitch; subres_data[face * num_mip_maps_ + i].SysMemSlicePitch = init_data[face * num_mip_maps_ + i].slice_pitch; } } } ID3D11Texture2D* d3d_tex; TIF(d3d_device_->CreateTexture2D(&desc_, (init_data != nullptr) ? &subres_data[0] : nullptr, &d3d_tex)); d3dTextureCube_ = MakeCOMPtr(d3d_tex); this->UpdateParams(); if ((access_hint & (EAH_GPU_Read | EAH_Generate_Mips)) && (num_mip_maps_ > 1)) { this->RetriveD3DShaderResourceView(0, array_size_, 0, num_mip_maps_); } }
//IVMRSurfaceAllocator9 HRESULT DShowVMR9Allocator::InitializeDevice(DWORD_PTR dwUserID, VMR9AllocationInfo* lpAllocInfo, DWORD* lpNumBuffers) { if (dwUserID != USER_ID) { return S_OK; } if (nullptr == lpNumBuffers) { return E_POINTER; } if (!vmr_surf_alloc_notify_) { return E_FAIL; } HRESULT hr = S_OK; // NOTE: // we need to make sure that we create textures because // surfaces can not be textured onto a primitive. lpAllocInfo->dwFlags |= VMR9AllocFlag_TextureSurface; this->DeleteSurfaces(); surfaces_.resize(*lpNumBuffers); hr = vmr_surf_alloc_notify_->AllocateSurfaceHelper(lpAllocInfo, lpNumBuffers, &surfaces_[0]); // If we couldn't create a texture surface and // the format is not an alpha format, // then we probably cannot create a texture. // So what we need to do is create a private texture // and copy the decoded images onto it. if (FAILED(hr) && !(lpAllocInfo->dwFlags & VMR9AllocFlag_3DRenderTarget)) { this->DeleteSurfaces(); lpAllocInfo->dwFlags &= ~VMR9AllocFlag_TextureSurface; lpAllocInfo->dwFlags |= VMR9AllocFlag_OffscreenSurface; TIF(vmr_surf_alloc_notify_->AllocateSurfaceHelper(lpAllocInfo, lpNumBuffers, &surfaces_[0])); } RenderFactory& rf = Context::Instance().RenderFactoryInstance(); ElementFormat fmt; if (Context::Instance().Config().graphics_cfg.gamma) { if (rf.RenderEngineInstance().DeviceCaps().texture_format_support(EF_ABGR8_SRGB)) { fmt = EF_ABGR8_SRGB; } else { if (rf.RenderEngineInstance().DeviceCaps().texture_format_support(EF_ARGB8_SRGB)) { fmt = EF_ARGB8_SRGB; } else { if (rf.RenderEngineInstance().DeviceCaps().texture_format_support(EF_ABGR8)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(rf.RenderEngineInstance().DeviceCaps().texture_format_support(EF_ARGB8)); fmt = EF_ARGB8; } } } } else { if (rf.RenderEngineInstance().DeviceCaps().texture_format_support(EF_ABGR8)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(rf.RenderEngineInstance().DeviceCaps().texture_format_support(EF_ARGB8)); fmt = EF_ARGB8; } } present_tex_ = rf.MakeTexture2D(lpAllocInfo->dwWidth, lpAllocInfo->dwHeight, 1, 1, fmt, 1, 0, EAH_CPU_Write | EAH_GPU_Read, nullptr); IDirect3DSurface9* surf; TIF(d3d_device_->CreateOffscreenPlainSurface(lpAllocInfo->dwWidth, lpAllocInfo->dwHeight, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, nullptr)); cache_surf_ = MakeCOMPtr(surf); return S_OK; }