//////////////////////////////////////////////////////////////////////////// // Function: Load the document from memory encoded bytes. //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::LoadFromMemory(PBYTE pData, ULONG ulLen) { // Create a stream and write the bytes to it IStreamPtr pStream = NULL; HRESULT hr = ::CreateStreamOnHGlobal(NULL, true/*fDeleteOnRelease*/, &pStream); hr = CheckHR(hr, "load from memory"); ULONG ulWritten; pStream->Write(pData, ulLen, &ulWritten); // Reset the stream back to the beginning LARGE_INTEGER li = {0, 0}; hr = pStream->Seek(li, STREAM_SEEK_SET, NULL); hr = CheckHR(hr, "in load from memory seek"); // Now, load the document from the stream IPersistStreamInitPtr pPSI = m_pDoc; if (pPSI == NULL) return E_FAIL; hr = pPSI->Load(pStream); hr = CheckHR(hr, "load from memory load"); hr = CheckLoad(); return hr; }
void CGNetUpdater::Init() { CheckHR(m_pMasterServer.CreateInstance(__uuidof(SHAREDLib::RemoteMasterServer))); CheckHR(AtlAdvise(m_pMasterServer, (IGameEvents *) this, IID_IRemoteMasterServerEvents, &m_dwMasterServerCookie)); CheckHR(AtlAdvise(m_pMasterServer, (IGameEvents *) this, IID_IGameEvents, &m_dwMasterServerCookie2)); }
//////////////////////////////////////////////////////////////////////////// // Function: Load an XML document from a given stream object //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::LoadStream(CString strFileName) { HRESULT hr = S_OK; // Create an IStream object for reading the specified URL. char szURL[MAX_PATH]; if (!strncmp(strFileName, "http:", 5)) strcpy(szURL, strFileName); else ::GetFullPathNameA(strFileName, MAX_PATH, szURL, NULL); IStreamPtr pStream = NULL; hr = ::URLOpenBlockingStreamA(0, szURL, &pStream, 0, 0); hr = CheckHR(hr, "in load stream: URLOpenBlockingStreamA"); IPersistStreamInitPtr pPSI = m_pDoc; if (pPSI == NULL) return E_FAIL; hr = pPSI->Load(pStream); hr = CheckHR(hr, "in load stream"); // Since we don't know whether this was a URLStream or not. WaitForCompletion(); hr = CheckLoad(); return hr; }
XFBEncoder::XFBEncoder() { ID3D12Resource* texture; CheckHR(D3D::device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, XFB_TEXTURE_WIDTH, XFB_TEXTURE_HEIGHT, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET), D3D12_RESOURCE_STATE_RENDER_TARGET, nullptr, IID_PPV_ARGS(&texture))); m_yuyv_texture = new D3DTexture2D(texture, TEXTURE_BIND_FLAG_SHADER_RESOURCE | TEXTURE_BIND_FLAG_RENDER_TARGET, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM); SAFE_RELEASE(texture); CheckHR(D3D::device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(ROUND_UP(XFB_TEXTURE_WIDTH * sizeof(u32), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) * MAX_XFB_HEIGHT), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_readback_buffer))); m_upload_buffer = std::make_unique<D3DStreamBuffer>(XFB_UPLOAD_BUFFER_SIZE, XFB_UPLOAD_BUFFER_SIZE, nullptr); m_encode_params_buffer = std::make_unique<D3DStreamBuffer>(XFB_ENCODER_PARAMS_BUFFER_SIZE, XFB_ENCODER_PARAMS_BUFFER_SIZE, nullptr); }
bool Graphics2D::draw() { // 1. clear the back buffer to black (0,0,0) and the z buffer to 1 HRESULT hr=m_d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0); if (!CheckHR(hr)) return false; // 2. begin the scene hr=m_d3dDevice->BeginScene(); if (!CheckHR(hr)) return false; // 3. draw me some sprites!! if (!DrawSprites()) return false; // 4. End the scene and present it hr=m_d3dDevice->EndScene(); if (!CheckHR(hr)) return false; // 5. ...... ta da! hr=m_d3dDevice->Present(NULL,NULL,NULL,NULL); if (!CheckHR(hr)) return false; return true; }
void PSTextureEncoder::Init() { // Create output texture RGBA format D3D12_RESOURCE_DESC out_tex_desc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_B8G8R8A8_UNORM, EFB_WIDTH * 4, EFB_HEIGHT / 4, 1, 0, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET); D3D12_CLEAR_VALUE optimized_clear_value = {DXGI_FORMAT_B8G8R8A8_UNORM, {0.0f, 0.0f, 0.0f, 1.0f}}; CheckHR(D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &out_tex_desc, D3D12_RESOURCE_STATE_COPY_SOURCE, &optimized_clear_value, IID_PPV_ARGS(&m_out))); D3D::SetDebugObjectName12(m_out, "efb encoder output texture"); // Create output render target view D3D12_RENDER_TARGET_VIEW_DESC tex_rtv_desc = { DXGI_FORMAT_B8G8R8A8_UNORM, // DXGI_FORMAT Format; D3D12_RTV_DIMENSION_TEXTURE2D // D3D12_RTV_DIMENSION ViewDimension; }; tex_rtv_desc.Texture2D.MipSlice = 0; D3D::rtv_descriptor_heap_mgr->Allocate(&m_out_rtv_cpu); D3D::device12->CreateRenderTargetView(m_out, &tex_rtv_desc, m_out_rtv_cpu); // Create output staging buffer CheckHR(D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer( D3D::AlignValue(static_cast<unsigned int>(out_tex_desc.Width) * 4, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) * out_tex_desc.Height), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_out_readback_buffer))); D3D::SetDebugObjectName12(m_out_readback_buffer, "efb encoder output staging buffer"); // Create constant buffer for uploading data to shaders. Need to align to 256 bytes. unsigned int encode_params_buffer_size = (sizeof(EFBEncodeParams) + 0xff) & ~0xff; CheckHR(D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(encode_params_buffer_size), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_encode_params_buffer))); D3D::SetDebugObjectName12(m_encode_params_buffer, "efb encoder params buffer"); // NOTE: This upload buffer is okay to overwrite each time, since we block until completion when // it's used anyway. D3D12_RANGE read_range = {}; CheckHR(m_encode_params_buffer->Map(0, &read_range, &m_encode_params_buffer_data)); m_ready = true; }
HRESULT VideoEncoder::Initialize() { HRESULT hr = S_OK; this->m_logFileStream = ofstream(this->m_logFile); if (this->m_inputFile == L"") { this->m_logFileStream << "输入短影配置文件无效." << endl; return ERROR_FILE_INVALID; } // 初始化 COM. hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); // COM 未被调用代码初始化. 因此我们初始化它. if (SUCCEEDED(hr)) { this->m_logFileStream << "COM初始化成功." << endl; this->m_COMInitializedInDll = true; } // COM被调用代码初始化. else if (hr == RPC_E_CHANGED_MODE || hr == S_FALSE) { this->m_COMInitializedInDll = false; } // COM初始化失败. else { return hr; } // 创建WIC 工厂 CheckHR(CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&this->m_pIWICFactory) )); // 启动Media Foundation. CheckHR(MFStartup(MF_VERSION)); cleanup: if (!SUCCEEDED(hr)) { DWORD error = GetLastError(); this->m_logFileStream << "意外错误: " << error << endl; } return hr; }
PerfQuery::PerfQuery() { D3D12_QUERY_HEAP_DESC desc = {D3D12_QUERY_HEAP_TYPE_OCCLUSION, PERF_QUERY_BUFFER_SIZE, 0}; CheckHR(D3D::device12->CreateQueryHeap(&desc, IID_PPV_ARGS(&m_query_heap))); CheckHR(D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(QUERY_READBACK_BUFFER_SIZE), D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&m_query_readback_buffer))); m_tracking_fence = D3D::command_list_mgr->RegisterQueueFenceCallback(this, &PerfQuery::QueueFenceCallback); }
int BBox::Get(int index) { if (!s_bbox_buffer) return 0; if (s_bbox_gpu_dirty) { D3D::command_list_mgr->CPUAccessNotify(); // Copy from real buffer to staging buffer, then block until we have the results. D3D::ResourceBarrier(D3D::current_command_list, s_bbox_buffer, s_current_bbox_state, D3D12_RESOURCE_STATE_COPY_SOURCE, 0); s_current_bbox_state = D3D12_RESOURCE_STATE_COPY_SOURCE; D3D::current_command_list->CopyBufferRegion(s_bbox_staging_buffer, 0, s_bbox_buffer, 0, BBOX_BUFFER_SIZE); D3D::command_list_mgr->ExecuteQueuedWork(true); D3D12_RANGE read_range = { 0, BBOX_BUFFER_SIZE }; void* bbox_staging_buffer_map = nullptr; CheckHR(s_bbox_staging_buffer->Map(0, &read_range, &bbox_staging_buffer_map)); memcpy(s_bbox_shadow_copy, bbox_staging_buffer_map, BBOX_BUFFER_SIZE); D3D12_RANGE write_range = {}; s_bbox_staging_buffer->Unmap(0, &write_range); s_bbox_gpu_dirty = false; } return s_bbox_shadow_copy[index]; }
void PerfQuery::FlushOne() { size_t index = m_query_read_pos; ActiveQuery& entry = m_query_buffer[index]; // Has the command list been executed yet? if (entry.fence_value == m_next_fence_value) D3D::command_list_mgr->ExecuteQueuedWork(false); // Block until the fence is reached D3D::command_list_mgr->WaitOnCPUForFence(m_tracking_fence, entry.fence_value); // Copy from readback buffer to local void* readback_buffer_map; D3D12_RANGE read_range = {sizeof(UINT64) * index, sizeof(UINT64) * (index + 1)}; CheckHR(m_query_readback_buffer->Map(0, &read_range, &readback_buffer_map)); UINT64 result; memcpy(&result, reinterpret_cast<u8*>(readback_buffer_map) + sizeof(UINT64) * index, sizeof(UINT64)); D3D12_RANGE write_range = {}; m_query_readback_buffer->Unmap(0, &write_range); // NOTE: Reported pixel metrics should be referenced to native resolution m_results[entry.query_type] += (u32)(result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight()); m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size(); m_query_count--; }
TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config) { if (config.rendertarget) { D3DTexture2D* texture = D3DTexture2D::Create(config.width, config.height, static_cast<D3D11_BIND_FLAG>((static_cast<int>(D3D11_BIND_RENDER_TARGET) | static_cast<int>(D3D11_BIND_SHADER_RESOURCE))), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM, 1, config.layers); TCacheEntry* entry = new TCacheEntry(config, texture); entry->m_texture_srv_cpu_handle = texture->GetSRV12CPU(); entry->m_texture_srv_gpu_handle = texture->GetSRV12GPU(); entry->m_texture_srv_gpu_handle_cpu_shadow = texture->GetSRV12GPUCPUShadow(); return entry; } else { ID3D12Resource* texture_resource = nullptr; D3D12_RESOURCE_DESC texture_resource_desc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, config.width, config.height, 1, config.levels); CheckHR( D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC(texture_resource_desc), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, nullptr, IID_PPV_ARGS(&texture_resource) ) ); D3DTexture2D* texture = new D3DTexture2D( texture_resource, D3D11_BIND_SHADER_RESOURCE, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, false, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE ); TCacheEntry* const entry = new TCacheEntry( config, texture ); entry->m_texture_srv_cpu_handle = texture->GetSRV12CPU(); entry->m_texture_srv_gpu_handle = texture->GetSRV12GPU(); entry->m_texture_srv_gpu_handle_cpu_shadow = texture->GetSRV12GPUCPUShadow(); // EXISTINGD3D11TODO: better debug names D3D::SetDebugObjectName12(entry->m_texture->GetTex12(), "a texture of the TextureCache"); SAFE_RELEASE(texture_resource); return entry; } }
void Read(const UidType& key, const u8* value, u32 value_size) { ID3DBlob* blob = nullptr; CheckHR(d3d_create_blob(value_size, &blob)); memcpy(blob->GetBufferPointer(), value, value_size); ShaderCache::InsertByteCode<UidType, ShaderCacheType>(key, cache, blob); }
CXMLDocument::CXMLDocument() { m_pCallbackFunction = NULL; m_pCallbackParam = NULL; m_pDoc = NULL; HRESULT hr = m_pDoc.CreateInstance(MSXML2::CLSID_DOMDocument); //j (CLSID_FreeThreadedDOMDocument); hr = CheckHR(hr, "in the constructor"); }
//////////////////////////////////////////////////////////////////////////// // Function: Create an XML DOM Document from Scratch in memory //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::Build() { // Create a root node MSXML2::IXMLDOMNodePtr pRoot; m_pDoc->createNode(CComVariant(MSXML2::NODE_ELEMENT), CComBSTR("Root"), NULL, &pRoot); // add child nodes HRESULT hr = S_OK; for (int i = 0; i < 10; i++) { MSXML2::IXMLDOMNodePtr pNode; m_pDoc->createNode(CComVariant(MSXML2::NODE_ELEMENT), CComBSTR("Order"), NULL, &pNode); MSXML2::IXMLDOMElementPtr pElement = pNode; if (pElement != NULL) pElement->setAttribute(CComBSTR("id"), CComVariant(i)); MSXML2::IXMLDOMNodePtr p0 = NULL; CComVariant after; hr = pRoot->insertBefore(pNode, after, &p0); hr = CheckHR(hr, "inserting node"); // The XML Document should now own the node. for (int j = 0; j < 10; j++) { MSXML2::IXMLDOMNodePtr pNode2; m_pDoc->createNode(CComVariant(MSXML2::NODE_ELEMENT), CComBSTR("Item"), NULL, &pNode2); MSXML2::IXMLDOMElementPtr pElement2 = pNode2; if (pElement2 != NULL) pElement2->setAttribute(CComBSTR("id"), CComVariant((i*10) + j)); MSXML2::IXMLDOMNodePtr p1 = NULL; CComVariant after; hr = p0->insertBefore(pNode2, after, &p1); hr = CheckHR(hr, "inserting node"); // The XML Document should now own the node. } } // Now attach this new subtree to the document. m_pDoc->appendChild(pRoot, NULL); return hr; }
HRESULT VideoEncoder::WriteTransitionSample(UINT64 sampleDuration, TransitionBase* pTransition, DWORD streamIndex, LONGLONG* startTime) { HRESULT hr = S_OK; IMFMediaBuffer* pMediaBuffer = nullptr; BYTE* pFrameBuffer = nullptr; IMFSample* pSample = nullptr; BYTE* pOutputFrame = nullptr; for (DWORD i = 0; i < sampleDuration; i++) { CheckHR(MFCreateMemoryBuffer(this->m_frameBufferSize, &pMediaBuffer)); pMediaBuffer->Lock(&pFrameBuffer, nullptr, nullptr); float time = (float)i / (float)sampleDuration; pOutputFrame = pTransition->GetOutputFrame(time); CheckHR(MFCopyImage(pFrameBuffer, this->m_frameStride, pOutputFrame, this->m_frameStride, this->m_frameStride, this->m_frameHeight)); CheckHR(pMediaBuffer->Unlock()); CheckHR(pMediaBuffer->SetCurrentLength(this->m_frameBufferSize)); CheckHR(MFCreateSample(&pSample)); CheckHR(pSample->AddBuffer(pMediaBuffer)); CheckHR(pSample->SetSampleTime(*startTime)); CheckHR(pSample->SetSampleDuration(this->GetFrameDuration())); CheckHR(this->m_pSinkWriter->WriteSample(streamIndex, pSample)); (*startTime) += this->GetFrameDuration(); // 释放示例资源. SafeRelease(&pMediaBuffer); SafeRelease(&pSample); if (pOutputFrame != nullptr) { delete pOutputFrame; pOutputFrame = nullptr; } } cleanup: if (!SUCCEEDED(hr)) { DWORD error = GetLastError(); this->m_logFileStream << "意外错误: " << error << endl; } SafeRelease(&pMediaBuffer); SafeRelease(&pSample); if (pOutputFrame != nullptr) { delete pOutputFrame; pOutputFrame = nullptr; } return hr; }
void GeometryShaderCache::Init() { unsigned int gscbuf12sizeInBytes = gscbuf12paddedSize * gscbuf12Slots; CheckHR( D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(gscbuf12sizeInBytes), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&gscbuf12) ) ); D3D::SetDebugObjectName12(gscbuf12, "vertex shader constant buffer used to emulate the GX pipeline"); // Obtain persistent CPU pointer to GS Constant Buffer CheckHR(gscbuf12->Map(0, nullptr, &gscbuf12data)); // used when drawing clear quads D3D::CompileGeometryShader(clear_shader_code, &ClearGeometryShaderBlob); // used for buffer copy D3D::CompileGeometryShader(copy_shader_code, &CopyGeometryShaderBlob); Clear(); if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); // Intentionally share the same cache as DX11, as the shaders are identical. Reduces recompilation when switching APIs. std::string cache_filename = StringFromFormat("%sdx11-%s-gs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), SConfig::GetInstance().m_strUniqueID.c_str()); GeometryShaderCacheInserter inserter; g_gs_disk_cache.OpenAndRead(cache_filename, inserter); if (g_Config.bEnableShaderDebugging) Clear(); last_entry = nullptr; last_uid = {}; }
//////////////////////////////////////////////////////////////////////////// // Function: Walk all the Elements in a loaded XML document. //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::WalkTree(CString& strSearchPattern) { HRESULT hr = S_OK; if (strSearchPattern.IsEmpty()) { MSXML2::IXMLDOMNodePtr pNode = m_pDoc; if (pNode == NULL) return E_FAIL; hr = WalkTree(0/*iLevel*/, pNode); } else { //j ("//video"); //j ("//video[@id='crap1']"); //j ("//video[@id='crap1']"); // filter the nodes using the search pattern MSXML2::IXMLDOMNodeListPtr pNodeList = NULL; hr = m_pDoc->selectNodes(CComBSTR(strSearchPattern), &pNodeList); hr = CheckHR(hr, "in the search pattern"); // get the length of the resulting node list if (pNodeList) { long lLength; hr = pNodeList->get_length(&lLength); hr = CheckHR(hr, "retrieving node list length"); MSXML2::IXMLDOMNodePtr pNode = NULL; for (long i = 0; i < lLength; i++) { hr = pNodeList->get_item(i, &pNode); hr = WalkTree(0/*iLevel*/, pNode); if (hr != S_OK) return hr; } } } return hr; }
//////////////////////////////////////////////////////////////////////////// // Function: Load an XML Document from the specified file or URL synchronously. //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::Load(CString strURLFileName, bool bAsync) { // set asynchronous loading flag HRESULT hr = m_pDoc->put_async(bAsync ? VARIANT_TRUE : VARIANT_FALSE); hr = CheckHR(hr, "in load: put_async"); // Load xml document from the given URL or file path VARIANT_BOOL vbIsSuccessful = false; hr = m_pDoc->load(CComVariant(strURLFileName), &vbIsSuccessful); hr = CheckHR(hr, "in load"); // Now wait for download to complete! if (bAsync) WaitForCompletion(); hr = CheckLoad(); return hr; }
void VertexManager::CreateDeviceObjects() { m_vertexDrawOffset = 0; m_indexDrawOffset = 0; CheckHR( D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(MAX_VBUFFER_SIZE), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_vertexBuffer) ) ); D3D::SetDebugObjectName12(m_vertexBuffer, "Vertex Buffer of VertexManager"); CheckHR(m_vertexBuffer->Map(0, nullptr, &m_vertexBufferData)); CheckHR( D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(MAX_IBUFFER_SIZE), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_indexBuffer) ) ); D3D::SetDebugObjectName12(m_indexBuffer, "Index Buffer of VertexManager"); CheckHR(m_indexBuffer->Map(0, nullptr, &m_indexBufferData)); SetIndexBuffer(); // Use CPU-only memory if the GPU won't be reading from the buffers, // since reading upload heaps on the CPU is slow.. vertexCpuBuffer = new u8[MAXVBUFFERSIZE]; indexCpuBuffer = new u8[MAXIBUFFERSIZE]; }
//////////////////////////////////////////////////////////////////////////// // Function: Return an in-memory encoded version of the XML data which // we can squirrel away in memory for use later. This is better // and faster than storing the document in a huge BSTR via get_xml. //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::PersistToMemory(PBYTE* ppBuffer, ULONG* pLen) { // Create stream in global memory and save the xml document to it IStreamPtr pStream = NULL; HRESULT hr = ::CreateStreamOnHGlobal(NULL, true/*fDeleteOnRelease*/, &pStream); hr = CheckHR(hr, "in persist to memory"); IPersistStreamInitPtr pPSI = m_pDoc; if (pPSI == NULL) return E_FAIL; hr = pPSI->Save(pStream, true); hr = CheckHR(hr, "in persist to memory save"); // now to get the real size of the stream, we have to use the // seek function. You can't depend on the GlobalSize because // the hGlobal might have been rounded up to some paragraph boundary. LARGE_INTEGER li = {0, 0}; ULARGE_INTEGER uli; hr = pStream->Seek(li, STREAM_SEEK_CUR, &uli); hr = CheckHR(hr, "in persist to memory seek"); ULONG size = (int)uli.QuadPart; *pLen = size; BYTE* pbData = new BYTE[size]; if (pbData == NULL) hr = E_OUTOFMEMORY; else { *ppBuffer = pbData; HGLOBAL hGlobal; hr = ::GetHGlobalFromStream(pStream, &hGlobal); hr = CheckHR(hr, "in persist to memory"); ::memcpy(pbData, (PBYTE)GlobalLock(hGlobal), size); GlobalUnlock(hGlobal); } return hr; }
void BBox::Init() { memset(s_bbox_shadow_copy, 0, sizeof(s_bbox_shadow_copy)); s_bbox_cpu_dirty = true; s_bbox_gpu_dirty = true; CD3DX12_RESOURCE_DESC buffer_desc(CD3DX12_RESOURCE_DESC::Buffer(BBOX_BUFFER_SIZE, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, 0)); CD3DX12_RESOURCE_DESC staging_buffer_desc(CD3DX12_RESOURCE_DESC::Buffer(BBOX_BUFFER_SIZE, D3D12_RESOURCE_FLAG_NONE, 0)); CheckHR(D3D::device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &buffer_desc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(&s_bbox_buffer))); s_current_bbox_state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; CheckHR(D3D::device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK), D3D12_HEAP_FLAG_NONE, &staging_buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&s_bbox_staging_buffer))); s_bbox_stream_buffer = std::make_unique<D3DStreamBuffer>(BBOX_STREAM_BUFFER_SIZE, BBOX_STREAM_BUFFER_SIZE, nullptr); // D3D12 root signature UAV must be raw or structured buffers, not typed. Since we used a typed buffer, // we have to use a descriptor table. Luckily, we only have to allocate this once, and it never changes. D3D12_CPU_DESCRIPTOR_HANDLE cpu_descriptor_handle; if (!D3D::gpu_descriptor_heap_mgr->Allocate(&cpu_descriptor_handle, &s_bbox_descriptor_handle, nullptr, false)) PanicAlert("Failed to create bounding box UAV descriptor"); D3D12_UNORDERED_ACCESS_VIEW_DESC view_desc = { DXGI_FORMAT_R32_SINT, D3D12_UAV_DIMENSION_BUFFER }; view_desc.Buffer.FirstElement = 0; view_desc.Buffer.NumElements = 4; view_desc.Buffer.StructureByteStride = 0; view_desc.Buffer.CounterOffsetInBytes = 0; view_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; D3D::device->CreateUnorderedAccessView(s_bbox_buffer, nullptr, &view_desc, cpu_descriptor_handle); Bind(); }
//////////////////////////////////////////////////////////////////////////// // Helper function: Check load results //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::CheckLoad() { // And since we don't have the VARIANT_BOOL from load we // need to check the parse Error errorCode property to see // if everything went ok. MSXML2::IXMLDOMParseErrorPtr pXMLError = NULL; HRESULT hr = m_pDoc->get_parseError(&pXMLError); hr = CheckHR(hr, "getting parse error"); long lErrorCode = NULL; if (pXMLError) { hr = pXMLError->get_errorCode(&lErrorCode); hr = CheckHR(hr, "getting error code"); if (lErrorCode) hr = ReportError(pXMLError); } return lErrorCode; }
// Alternative setup method void ImageBuffer::AttachSurfaces(DisplayDevice *pDev, IDirectDrawSurface7 *pDDSFront, IDirectDrawSurface7 *pDDSBack) { if(!pDev || !pDDSFront) return; if(!pDDSBack) pDDSBack = pDDSFront; try { CheckHR(pDDSFront->QueryInterface(IID_IDirectDrawSurface7, (void **) &m_pDDSFront)); CheckHR(pDDSBack->QueryInterface(IID_IDirectDrawSurface7, (void **) &m_pDDSBack)); // Compute the color format conversion parameters m_ddsdFront.dwSize = sizeof(DDSURFACEDESC2); CheckHR(m_pDDSFront->GetSurfaceDesc(&m_ddsdFront)); m_ddsdBack.dwSize = sizeof(DDSURFACEDESC2); CheckHR(m_pDDSBack->GetSurfaceDesc(&m_ddsdBack)); // Set blt target surface depending on wether we will page flip or not m_pBltTarget = m_pDDSFront; // Record the properties of the buffer(s) we're creating device = pDev; width = m_ddsdFront.dwWidth; height = m_ddsdFront.dwHeight; m_bFrontRectValid = false; ZeroMemory(&m_rcFront, sizeof(m_rcFront)); ComputeColorShifts(); // Everything worked, so finish up and return m_bReady = TRUE; } catch(_com_error e) { MonoPrint("ImageBuffer::AttachSurfaces - Error 0x%X\n", e.Error()); } }
D3DTexture2D* D3DTexture2D::Create(unsigned int width, unsigned int height, D3D11_BIND_FLAG bind, D3D11_USAGE usage, DXGI_FORMAT fmt, unsigned int levels, unsigned int slices, D3D12_SUBRESOURCE_DATA* data) { ID3D12Resource* texture12 = nullptr; D3D12_RESOURCE_DESC texdesc12 = CD3DX12_RESOURCE_DESC::Tex2D( fmt, width, height, slices, levels ); D3D12_CLEAR_VALUE optimized_clear_value = {}; optimized_clear_value.Format = fmt; if (bind & D3D11_BIND_RENDER_TARGET) { texdesc12.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; optimized_clear_value.Color[0] = 0.0f; optimized_clear_value.Color[1] = 0.0f; optimized_clear_value.Color[2] = 0.0f; optimized_clear_value.Color[3] = 1.0f; } if (bind & D3D11_BIND_DEPTH_STENCIL) { texdesc12.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; optimized_clear_value.DepthStencil.Depth = 0.0f; optimized_clear_value.DepthStencil.Stencil = 0; } CheckHR( D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC(texdesc12), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, &optimized_clear_value, IID_PPV_ARGS(&texture12) ) ); D3D::SetDebugObjectName12(texture12, "Texture created via D3DTexture2D::Create"); D3DTexture2D* ret = new D3DTexture2D(texture12, bind, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, false, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); if (data) { DX12::D3D::ReplaceRGBATexture2D(texture12, reinterpret_cast<const u8*>(data->pData), width, height, static_cast<unsigned int>(data->RowPitch), 0, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); } SAFE_RELEASE(texture12); return ret; }
HRESULT CXMLDocument::LoadString(CString strXML) { HRESULT hr = S_OK; VARIANT_BOOL vbIsSuccessful = false; hr = m_pDoc->put_validateOnParse(VARIANT_TRUE); hr = m_pDoc->loadXML(CComBSTR(strXML), &vbIsSuccessful); hr = CheckHR(hr, "in load"); hr = CheckLoad(); return hr; }
void D3DStreamBuffer::AllocateBuffer(size_t size) { // First, put existing buffer (if it exists) in deferred destruction list. if (m_buffer) { m_buffer->Unmap(0, nullptr); D3D::command_list_mgr->DestroyResourceAfterCurrentCommandListExecuted(m_buffer); m_buffer = nullptr; } CheckHR( D3D::device12->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(size), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_buffer) ) ); CheckHR(m_buffer->Map(0, nullptr, &m_buffer_cpu_address)); m_buffer_gpu_address = m_buffer->GetGPUVirtualAddress(); m_buffer_size = size; // Start at the beginning of the new buffer. m_buffer_gpu_completion_offset = 0; m_buffer_current_allocation_offset = 0; m_buffer_offset = 0; // Notify observers. if (m_buffer_reallocation_notification != nullptr) *m_buffer_reallocation_notification = true; // If we had any fences queued, they are no longer relevant. ClearFences(); }
//////////////////////////////////////////////////////////////////////////// // Helper function: Wait for async download to complete //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::WaitForCompletion() { long ready = READYSTATE_UNINITIALIZED; HRESULT hr = m_pDoc->get_readyState(&ready); hr = CheckHR(hr, "in wait for completion"); MSG msg; while (ready != READYSTATE_COMPLETE) { GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); hr = m_pDoc->get_readyState(&ready); hr = CheckHR(hr, "in wait for completion"); } while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { GetMessage(&msg, NULL, 0, 0); DispatchMessage(&msg); } return S_OK; }
bool GetFormatMSE(const D3DXIMAGE_INFO& info, LPDIRECT3DSURFACE8 pSrcSurf, D3DFORMAT fmt, double& CMSE, double& AMSE) { LPDIRECT3DSURFACE8 pCompSurf = 0, pDstSurf = 0; HRESULT hr; // Compress int Width = PadPow2(info.Width), Height = PadPow2(info.Height); hr = pD3DDevice->CreateImageSurface(Width, Height, fmt, &pCompSurf); CheckHR(hr); hr = D3DXLoadSurfaceFromSurface(pCompSurf, NULL, NULL, pSrcSurf, NULL, NULL, D3DX_FILTER_NONE, 0); CheckHR(hr); // Decompress hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pDstSurf); CheckHR(hr); hr = D3DXLoadSurfaceFromSurface(pDstSurf, NULL, NULL, pCompSurf, NULL, NULL, D3DX_FILTER_NONE, 0); CheckHR(hr); pCompSurf->Release(); pCompSurf = 0; // calculate mean square error D3DLOCKED_RECT slr, dlr; hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY); CheckHR(hr); hr = pDstSurf->LockRect(&dlr, NULL, D3DLOCK_READONLY); CheckHR(hr); double CTSE = 0.0; // total colour square error double ATSE = 0.0; // total alpha square error RGBCOLOUR* src = (RGBCOLOUR*)slr.pBits; RGBCOLOUR* dst = (RGBCOLOUR*)dlr.pBits; for (UINT y = 0; y < info.Height; ++y) { for (UINT x = 0; x < info.Width; ++x) { CTSE += (src->b - dst->b) * (src->b - dst->b); CTSE += (src->g - dst->g) * (src->g - dst->g); CTSE += (src->r - dst->r) * (src->r - dst->r); ATSE += (src->a - dst->a) * (src->a - dst->a); ++src; ++dst; } src += (slr.Pitch - info.Width*sizeof(RGBCOLOUR)) / sizeof(RGBCOLOUR); dst += (dlr.Pitch - info.Width*sizeof(RGBCOLOUR)) / sizeof(RGBCOLOUR); } CMSE = CTSE / double(info.Width * info.Height * 3); AMSE = ATSE / double(info.Width * info.Height); pSrcSurf->UnlockRect(); pDstSurf->UnlockRect(); pDstSurf->Release(); pDstSurf = 0; return true; }
//////////////////////////////////////////////////////////////////////////// // Helper function: //////////////////////////////////////////////////////////////////////////// HRESULT CXMLDocument::ReportError(MSXML2::IXMLDOMParseError* pXMLError) { CComBSTR bstrReason; HRESULT hr = pXMLError->get_reason(&bstrReason); hr = CheckHR(hr, "getting reason for the error"); CString strError = "Error: " + CString(bstrReason); long line = -1; hr = pXMLError->get_line(&line); hr = CheckHR(hr, "getting line"); if (line > 0) { long linePos = -1; hr = pXMLError->get_linepos(&linePos); hr = CheckHR(hr, "getting line position"); long lErrorCode = -1; hr = pXMLError->get_errorCode(&lErrorCode); hr = CheckHR(hr, "getting error code"); CComBSTR bstrURL; hr = pXMLError->get_url(&bstrURL); hr = CheckHR(hr, "getting URL"); CString strError1; strError1.Format(" @ line %d, position %d in \"%S\".", line, linePos, bstrURL); strError += strError1; } if (m_pCallbackFunction) m_pCallbackFunction(0, (LPCSTR)NULL, (LPCSTR)NULL, strError, m_pCallbackParam); return E_FAIL; }
int BBox::Get(int index) { if (!s_bbox_staging_buffer_map) { D3D::command_list_mgr->CPUAccessNotify(); // Copy from real buffer to staging buffer, then block until we have the results. D3D::ResourceBarrier(D3D::current_command_list, s_bbox_buffer, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE, 0); D3D::current_command_list->CopyBufferRegion(s_bbox_staging_buffer, 0, s_bbox_buffer, 0, BBOX_BUFFER_SIZE); D3D::ResourceBarrier(D3D::current_command_list, s_bbox_buffer, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0); D3D::command_list_mgr->ExecuteQueuedWork(true); D3D12_RANGE read_range = { 0, BBOX_BUFFER_SIZE }; CheckHR(s_bbox_staging_buffer->Map(0, &read_range, &s_bbox_staging_buffer_map)); } int value; memcpy(&value, &reinterpret_cast<int*>(s_bbox_staging_buffer_map)[index], sizeof(int)); return value; }