910e62b5创建于 1月15日历史提交
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/command_buffer/service/shared_image/d3d_image_utils.h"

#include <dawn/native/D3D11Backend.h>
#include <dawn/native/D3D12Backend.h>

#include "base/logging.h"
#include "base/notreached.h"
#include "base/strings/stringprintf.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/config/gpu_finch_features.h"

using dawn::native::d3d11::SharedTextureMemoryD3D11Texture2DDescriptor;
using dawn::native::d3d12::SharedBufferMemoryD3D12ResourceDescriptor;

namespace gpu {

bool ClearD3D11TextureToColor(
    const Microsoft::WRL::ComPtr<ID3D11Texture2D>& d3d11_texture,
    const SkColor4f& color) {
  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device;
  d3d11_texture->GetDevice(&d3d11_device);

  Microsoft::WRL::ComPtr<ID3D11RenderTargetView> render_target;
  HRESULT hr = d3d11_device->CreateRenderTargetView(d3d11_texture.Get(),
                                                    nullptr, &render_target);
  if (FAILED(hr)) {
    LOG(ERROR) << "CreateRenderTargetView failed: "
               << logging::SystemErrorCodeToString(hr);
    return false;
  }
  DCHECK(render_target);

  Microsoft::WRL::ComPtr<ID3D11DeviceContext> d3d11_device_context;
  d3d11_device->GetImmediateContext(&d3d11_device_context);
  DCHECK(d3d11_device_context);

  d3d11_device_context->ClearRenderTargetView(render_target.Get(), color.vec());

  return true;
}

wgpu::Texture CreateDawnSharedTexture(
    const wgpu::SharedTextureMemory& shared_texture_memory,
    wgpu::TextureUsage usage,
    wgpu::TextureUsage internal_usage,
    base::span<const wgpu::TextureFormat> view_formats) {
  wgpu::SharedTextureMemoryProperties properties;
  shared_texture_memory.GetProperties(&properties);

  wgpu::TextureDescriptor wgpu_texture_desc;
  wgpu_texture_desc.format = properties.format;
  wgpu_texture_desc.dimension = wgpu::TextureDimension::e2D;
  wgpu_texture_desc.size = properties.size;
  wgpu_texture_desc.mipLevelCount = 1;
  wgpu_texture_desc.sampleCount = 1;

  wgpu_texture_desc.usage = usage;
  wgpu_texture_desc.viewFormatCount =
      static_cast<uint32_t>(view_formats.size());
  wgpu_texture_desc.viewFormats = view_formats.data();

  wgpu::DawnTextureInternalUsageDescriptor wgpu_internal_usage_desc;
  wgpu_internal_usage_desc.internalUsage = internal_usage;
  wgpu_texture_desc.nextInChain = &wgpu_internal_usage_desc;

  return shared_texture_memory.CreateTexture(&wgpu_texture_desc);
}

wgpu::SharedTextureMemory CreateDawnSharedTextureMemory(
    const wgpu::Device& device,
    bool use_keyed_mutex,
    HANDLE handle) {
  wgpu::SharedTextureMemory shared_texture_memory;
  wgpu::SharedTextureMemoryDXGISharedHandleDescriptor shared_handle_desc;
  shared_handle_desc.handle = handle;
  shared_handle_desc.useKeyedMutex = use_keyed_mutex;

  wgpu::SharedTextureMemoryDescriptor desc;
  desc.nextInChain = &shared_handle_desc;
  desc.label = "SharedImageD3D_SharedTextureMemory_SharedHandle";

  shared_texture_memory = device.ImportSharedTextureMemory(&desc);

  // If ImportSharedTextureMemory is not successful and the device is not lost,
  // an error SharedTextureMemory object will be returned, which will cause an
  // error upon usage.
  if (shared_texture_memory.IsDeviceLost()) {
    LOG(ERROR) << "Failed to create shared texture memory due to device loss.";
    return nullptr;
  }

  return shared_texture_memory;
}

wgpu::SharedTextureMemory CreateDawnSharedTextureMemory(
    const wgpu::Device& device,
    Microsoft::WRL::ComPtr<ID3D11Texture2D> texture) {
  wgpu::SharedTextureMemory shared_texture_memory;
  SharedTextureMemoryD3D11Texture2DDescriptor texture2d_desc;
  texture2d_desc.texture = texture;

  wgpu::SharedTextureMemoryDescriptor desc;
  desc.nextInChain = &texture2d_desc;
  desc.label = "SharedImageD3D_SharedTextureMemory_Texture2D";
  shared_texture_memory = device.ImportSharedTextureMemory(&desc);

  // If ImportSharedTextureMemory is not successful and the device is not lost,
  // an error SharedTextureMemory object will be returned, which will cause an
  // error upon usage.
  if (shared_texture_memory.IsDeviceLost()) {
    LOG(ERROR) << "Failed to create shared texture memory due to device loss.";
    return nullptr;
  }

  return shared_texture_memory;
}

wgpu::Buffer CreateDawnSharedBuffer(
    const wgpu::SharedBufferMemory& shared_buffer_memory,
    wgpu::BufferUsage usage) {
  wgpu::SharedBufferMemoryProperties properties;
  shared_buffer_memory.GetProperties(&properties);

  wgpu::BufferDescriptor wgpu_buffer_desc;
  wgpu_buffer_desc.size = properties.size;
  wgpu_buffer_desc.usage = usage;

  return shared_buffer_memory.CreateBuffer(&wgpu_buffer_desc);
}

wgpu::SharedBufferMemory CreateDawnSharedBufferMemory(
    const wgpu::Device& device,
    Microsoft::WRL::ComPtr<ID3D12Resource> resource) {
  wgpu::SharedBufferMemory shared_buffer_memory;
  SharedBufferMemoryD3D12ResourceDescriptor d3d12_resource_desc;
  d3d12_resource_desc.resource = std::move(resource);

  wgpu::SharedBufferMemoryDescriptor desc;
  desc.nextInChain = &d3d12_resource_desc;
  desc.label = "SharedBufferD3D_SharedBufferMemory_Resource";
  shared_buffer_memory = device.ImportSharedBufferMemory(&desc);

  // If ImportSharedBufferMemory is not successful and the device is not lost,
  // an error SharedBufferMemory object will be returned, which will cause an
  // error upon usage.
  if (shared_buffer_memory.IsDeviceLost()) {
    LOG(ERROR) << "Failed to create shared buffer memory due to device loss.";
    return nullptr;
  }

  return shared_buffer_memory;
}

wgpu::SharedFence CreateDawnSharedFence(
    const wgpu::Device& device,
    scoped_refptr<gfx::D3DSharedFence> fence) {
  wgpu::SharedFence shared_fence;
  wgpu::SharedFenceDXGISharedHandleDescriptor dxgi_desc;
  dxgi_desc.handle = fence->GetSharedHandle();
  wgpu::SharedFenceDescriptor fence_desc;
  fence_desc.nextInChain = &dxgi_desc;

  shared_fence = device.ImportSharedFence(&fence_desc);

  return shared_fence;
}

std::string D3D11TextureDescToString(const D3D11_TEXTURE2D_DESC& desc) {
  return base::StringPrintf(
      "width=%u,height=%u,miplevels=%u,arraysize=%u,format=%u,samplecount=%u,"
      "samplequality=%u,usage=%u,bindflags=%08x,cpuaccessflags=%08x,"
      "miscflags=%08x",
      desc.Width, desc.Height, desc.MipLevels, desc.ArraySize, desc.Format,
      desc.SampleDesc.Count, desc.SampleDesc.Quality, desc.Usage,
      desc.BindFlags, desc.CPUAccessFlags, desc.MiscFlags);
}

}  // namespace gpu