void XFBEncoder::DecodeToTexture(D3DTexture2D* dst_texture, const u8* src, u32 src_width, u32 src_height) { _assert_msg_(VIDEO, src_width <= MAX_XFB_WIDTH && src_height <= MAX_XFB_HEIGHT, "XFB source does not exceed maximum size"); // Copy to XFB upload buffer. Each row has to be done separately due to pitch differences. u32 buffer_pitch = ROUND_UP(src_width / 2 * sizeof(u32), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); m_upload_buffer->AllocateSpaceInBuffer(buffer_pitch * src_height, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT); for (u32 row = 0; row < src_height; row++) { const u8* row_src = src + (src_width * 2) * row; u8* row_dst = reinterpret_cast<u8*>(m_upload_buffer->GetCPUAddressOfCurrentAllocation()) + buffer_pitch * row; memcpy(row_dst, row_src, src_width * 2); } // Copy from upload buffer to intermediate YUYV texture. D3D12_PLACED_SUBRESOURCE_FOOTPRINT src_footprint = { m_upload_buffer->GetOffsetOfCurrentAllocation(),{ DXGI_FORMAT_R8G8B8A8_UNORM, src_width / 2, src_height, 1, buffer_pitch } }; CD3DX12_TEXTURE_COPY_LOCATION src_location(m_upload_buffer->GetBuffer(), src_footprint); CD3DX12_TEXTURE_COPY_LOCATION dst_location(m_yuyv_texture->GetTex(), 0); CD3DX12_BOX src_box(0, 0, src_width / 2, src_height); m_yuyv_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_DEST); D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &src_box); // Convert YUYV texture to RGBA texture with pixel shader. CD3DX12_RECT src_texture_rect(0, 0, src_width / 2, src_height); dst_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); D3D::current_command_list->OMSetRenderTargets(1, &dst_texture->GetRTV(), FALSE, nullptr); D3D::SetViewportAndScissor(0, 0, src_width, src_height); D3D::DrawShadedTexQuad( m_yuyv_texture, &src_texture_rect, XFB_TEXTURE_WIDTH, XFB_TEXTURE_HEIGHT, StaticShaderCache::GetXFBDecodePixelShader(), StaticShaderCache::GetSimpleVertexShader(), StaticShaderCache::GetSimpleVertexShaderInputLayout(), {}, 0, DXGI_FORMAT_R8G8B8A8_UNORM, false, false); // XFB source textures are expected to be in shader resource state. dst_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); }
void dir_cpi_impl::sync_remove (saga::impl::void_t & ret, saga::url url, int flags) { instance_data idata (this); saga::url dir_url(idata->location_); boost::filesystem::path src_location (idata->location_.get_path(), boost::filesystem::native); // complete paths boost::filesystem::path src_path (url.get_path(), boost::filesystem::native); if ( ! src_path.has_root_path () ) src_location /= src_path; else src_location = src_path; bool is_src_dir = false; if(hdfsExists(fs_, src_location.string().c_str()) != 0) { SAGA_ADAPTOR_THROW("directory::remove: Can't remove directory: " "Does not exist", saga::DoesNotExist); } else { hdfsFileInfo *info; info = hdfsGetPathInfo(fs_, src_location.string().c_str()); if(info == NULL) { SAGA_ADAPTOR_THROW("file_cpi_impl::init failed", saga::NoSuccess); } if(info->mKind == kObjectKindDirectory) is_src_dir = true; else is_src_dir = false; hdfsFreeFileInfo(info, 1); } if (is_src_dir) { if (saga::name_space::Recursive != flags) { SAGA_ADAPTOR_THROW("directory::remove: Can't remove directory. " "Please use recursive mode!", saga::BadParameter); } else { saga_hdfs_delete(fs_, src_location.string().c_str()); } } else { saga_hdfs_delete(fs_, src_location.string().c_str()); } }
void dir_cpi_impl::sync_make_dir (saga::impl::void_t & ret, saga::url url, int flags) { instance_data idata (this); // verify current working directory is local saga::url dir_url(idata->location_); boost::filesystem::path src_location (idata->location_.get_path(), boost::filesystem::native); // complete paths boost::filesystem::path src_path (url.get_path(), boost::filesystem::native); if ( ! src_path.has_root_path () ) src_location /= src_path; else src_location = src_path; if(hdfsCreateDirectory(fs_, src_location.string().c_str()) != 0) { SAGA_ADAPTOR_THROW("Could not create directory", saga::NoSuccess); } }
void XFBEncoder::EncodeTextureToRam(u8* dst, u32 dst_pitch, u32 dst_height, D3DTexture2D* src_texture, const TargetRectangle& src_rect, u32 src_width, u32 src_height, float gamma) { // src_rect is in native coordinates // dst_pitch is in words u32 dst_width = dst_pitch / 2; u32 dst_texture_width = dst_width / 2; _assert_msg_(VIDEO, dst_width <= MAX_XFB_WIDTH && dst_height <= MAX_XFB_HEIGHT, "XFB destination does not exceed maximum size"); // Encode parameters constant buffer used by shader struct EncodeParameters { float src_rect[4]; float texel_size[4]; }; EncodeParameters parameters = { { static_cast<float>(src_rect.left) / static_cast<float>(src_width), static_cast<float>(src_rect.top) / static_cast<float>(src_height), static_cast<float>(src_rect.right) / static_cast<float>(src_width), static_cast<float>(src_rect.bottom) / static_cast<float>(src_height) }, { 1.0f / static_cast<float>(src_width), 1.0f / static_cast<float>(src_height), 0.0f, 0.0f } }; m_encode_params_buffer->AllocateSpaceInBuffer(sizeof(parameters), D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT); memcpy(m_encode_params_buffer->GetCPUAddressOfCurrentAllocation(), ¶meters, sizeof(parameters)); // Convert RGBA texture to YUYV intermediate texture. // Performs downscaling through a linear filter. Probably not ideal, but it's not going to look perfect anyway. CD3DX12_RECT src_texture_rect(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom); m_yuyv_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_RENDER_TARGET); D3D::current_command_list->OMSetRenderTargets(1, &m_yuyv_texture->GetRTV(), FALSE, nullptr); D3D::current_command_list->SetGraphicsRootConstantBufferView(DESCRIPTOR_TABLE_PS_CBVONE, m_encode_params_buffer->GetGPUAddressOfCurrentAllocation()); D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PS_CBV, true); D3D::SetViewportAndScissor(0, 0, dst_texture_width, dst_height); D3D::SetLinearCopySampler(); D3D::DrawShadedTexQuad( src_texture, &src_texture_rect, src_rect.GetWidth(), src_rect.GetHeight(), StaticShaderCache::GetXFBEncodePixelShader(), StaticShaderCache::GetSimpleVertexShader(), StaticShaderCache::GetSimpleVertexShaderInputLayout(), {}, 0, DXGI_FORMAT_R8G8B8A8_UNORM, false, false); // Copy from YUYV intermediate texture to readback buffer. It's likely the pitch here is going to be different to dst_pitch. u32 readback_pitch = ROUND_UP(dst_width * sizeof(u16), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); D3D12_PLACED_SUBRESOURCE_FOOTPRINT dst_footprint = { 0,{ DXGI_FORMAT_R8G8B8A8_UNORM, dst_texture_width, dst_height, 1, readback_pitch } }; CD3DX12_TEXTURE_COPY_LOCATION dst_location(m_readback_buffer, dst_footprint); CD3DX12_TEXTURE_COPY_LOCATION src_location(m_yuyv_texture->GetTex(), 0); CD3DX12_BOX src_box(0, 0, dst_texture_width, dst_height); m_yuyv_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_SOURCE); D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &src_box); // Wait until the GPU completes the copy. Resets back to known state automatically. D3D::command_list_mgr->ExecuteQueuedWork(true); // Copy from the readback buffer to dst. // Can't be done as one memcpy due to pitch difference. void* readback_texture_map; D3D12_RANGE read_range = { 0, readback_pitch * dst_height }; CheckHR(m_readback_buffer->Map(0, &read_range, &readback_texture_map)); for (u32 row = 0; row < dst_height; row++) { const u8* row_src = reinterpret_cast<u8*>(readback_texture_map) + readback_pitch * row; u8* row_dst = dst + dst_pitch * row; memcpy(row_dst, row_src, std::min(dst_pitch, readback_pitch)); } D3D12_RANGE write_range = {}; m_readback_buffer->Unmap(0, &write_range); }
void dir_cpi_impl::sync_move (saga::impl::void_t & ret, saga::url src, saga::url dest, int flags) { instance_data idata (this); // verify current working directory is local saga::url url(idata->location_); // handle the files boost::filesystem::path src_location (idata->location_.get_path(), boost::filesystem::native); boost::filesystem::path dst_location (src_location); // complete paths boost::filesystem::path src_path (src.get_path(), boost::filesystem::native); boost::filesystem::path dest_path (dest.get_path(), boost::filesystem::native); if ( ! src_path.has_root_path () ) src_location /= src_path; else src_location = src_path; if ( ! dest_path.has_root_path () ) dst_location /= dest_path; else dst_location = dest_path; bool is_src_dir; bool is_dst_dir; if(hdfsExists(fs_, src_location.string().c_str()) == 0) { //Check to see if it is a directory hdfsFileInfo *info; info = hdfsGetPathInfo(fs_, src_location.string().c_str()); if(info == NULL) { SAGA_ADAPTOR_THROW("file_cpi_impl::init failed", saga::NoSuccess); } if(info->mKind == kObjectKindDirectory) is_src_dir = true; else is_src_dir = false; hdfsFreeFileInfo(info, 1); } bool dst_exists = false; if(hdfsExists(fs_, dst_location.string().c_str()) == 0) { dst_exists = true; //Check to see if it is a directory hdfsFileInfo *info; info = hdfsGetPathInfo(fs_, dst_location.string().c_str()); if(info == NULL) { SAGA_ADAPTOR_THROW("file_cpi_impl::init failed", saga::NoSuccess); } if(info->mKind == kObjectKindDirectory) is_dst_dir = true; else is_dst_dir = false; hdfsFreeFileInfo(info, 1); } if (!is_src_dir && is_dst_dir) dst_location /= src_location.leaf(); if ((flags & saga::name_space::Overwrite) && dst_exists) { /* if (is_dst_dir) fs::remove_all(dst_location);*/ saga_hdfs_delete(fs_, dst_location.string().c_str()); } // if destination still exists raise an error dst_exists = false; if(hdfsExists(fs_, dst_location.string().c_str()) == 0) { SAGA_OSSTREAM strm; strm << "namespace_dir_cpi_impl<Base>::sync_move: " "target file already exists: " << dest.get_url(); SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::AlreadyExists); } if(hdfsMove(fs_, src_location.string().c_str(), fs_, dst_location.string().c_str()) != 0) { SAGA_ADAPTOR_THROW("Unable to move files", saga::NoSuccess); } }
void dir_cpi_impl::sync_copy (saga::impl::void_t & ret, saga::url src, saga::url dst, int flags) { instance_data idata (this); saga::url url(idata->location_); // handle the files boost::filesystem::path src_location (idata->location_.get_path(), boost::filesystem::native); boost::filesystem::path dst_location (src_location); // complete paths boost::filesystem::path src_path (src.get_path(), boost::filesystem::native); boost::filesystem::path dest_path (dst.get_path(), boost::filesystem::native); if ( ! src_path.has_root_path () ) src_location /= src_path; else src_location = src_path; if ( ! dest_path.has_root_path () ) dst_location /= dest_path; else dst_location = dest_path; bool is_src_dir = false; if(hdfsExists(fs_, src_location.string().c_str()) == 0) { //Check to see if it is a directory hdfsFileInfo *info; info = hdfsGetPathInfo(fs_, src_location.string().c_str()); if(info == NULL) { SAGA_ADAPTOR_THROW("file_cpi_impl::init failed", saga::NoSuccess); } if(info->mKind == kObjectKindDirectory) is_src_dir = true; hdfsFreeFileInfo(info, 1); } // src location refers to a is a directory if (is_src_dir) { SAGA_ADAPTOR_THROW("Cannot copy directory at moment.", saga::NotImplemented); } else { //Check to see if dst_location is a directory bool is_dst_dir = false; bool dst_exists = false; if(hdfsExists(fs_, dst_location.string().c_str()) == 0) { dst_exists = true; //Check to see if it is a directory hdfsFileInfo *info; info = hdfsGetPathInfo(fs_, dst_location.string().c_str()); if(info == NULL) { SAGA_ADAPTOR_THROW("file_cpi_impl::init failed", saga::NoSuccess); } if(info->mKind == kObjectKindDirectory) is_dst_dir = true; hdfsFreeFileInfo(info, 1); } else { SAGA_ADAPTOR_THROW("Path does not exists!", saga::NoSuccess); } if (is_dst_dir) dst_location /= src_location.leaf(); // remove the file/directory if it exists and we should overwrite if ((flags & saga::name_space::Overwrite) && dst_exists) { /* if (is_dst_dir) fs::remove_all(dst_location);*/ saga_hdfs_delete(fs_, dst_location.string().c_str()); } if(hdfsExists(fs_, dst_location.string().c_str()) == 0) { SAGA_OSSTREAM strm; strm << "namespace_dir_cpi_impl<Base>::sync_copy: " "target file already exists: " << dst.get_url(); SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::AlreadyExists); } if(hdfsCopy(fs_, src_location.string().c_str(), fs_, dst_location.string().c_str()) != 0) { SAGA_OSSTREAM strm; strm << "namespace_dir_cpi_impl<Base>::sync_copy: " "target file did not copy successfully: " << dst.get_url(); SAGA_ADAPTOR_THROW(SAGA_OSSTREAM_GETSTRING(strm), saga::NoSuccess); } } }