You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在原生Direct3D 11 DLL中使用Unity纹理遇DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN错误

DX11 Unity应用与原生C++ DLL共享纹理失败问题

问题背景

我有一个DX11模式的Unity应用,加载了自定义原生C++ DLL,该DLL创建了独立的D3D11 Device。现在需要无需拷贝CPU内存,直接在C++ DLL中使用Unity的RenderTexture,但调用OpenSharedResource1时失败。

Unity端代码

MyNativeLib.SetBuffers11(srcTexture.GetNativeTexturePtr());

注:srcTexture为Unity的RenderTexture对象

原生C++ DLL代码

void SetBuffers11(ID3D11Resource* colorRes)
{
    D3D11_TEXTURE2D_DESC texDesc;
    ID3D11Texture2D* tempColor;
    colorRes->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&tempColor);
    tempColor->GetDesc(&texDesc); // 此步骤正常执行,能获取正确描述

    ID3D11Resource* tempResource;
    HRESULT openResult = m_device->OpenSharedResource1(
        colorRes, __uuidof(ID3D11Resource), (void**)&tempResource); // 此步骤失败
    tempResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)(&tempColor));
    tempColor->GetDesc(&texDesc);
}

错误信息

  1. 尝试访问纹理数据时,触发错误:MISCELLANEOUS CORRUPTION #18: CORRUPTED_PARAMETER
  2. 调用OpenSharedResource失败,提示指针为NT类型,建议使用OpenSharedResource1;但调用OpenSharedResource1返回E_INVALIDARG,对应D3D11错误日志:
D3D11 ERROR: ID3D11Device::OpenSharedResource1: 
Returning E_INVALIDARG, meaning invalid parameters were passed. 
[ STATE_CREATION ERROR #381: DEVICE_OPEN_SHARED_RESOURCE_INVALIDARG_RETURN]

查询到的纹理描述

Format : 0x09 (DXGI_FORMAT_R16G16B16A16_TYPELESS)
Bind Flags : 0x20 | 0x08 (D3D11_BIND_SHADER_RESOURCE and D3D11_BIND_RENDER_TARGET)
CPU ACCESS : 0

解决方案

核心问题原因

直接传递ID3D11Resource*给OpenSharedResource1是错误的,该函数需要的是共享资源的句柄(HANDLE),而非资源指针本身。Unity返回的GetNativeTexturePtr()是D3D资源的指针,但跨设备/进程共享资源必须通过句柄实现。

修复步骤

  1. Unity端获取共享句柄:
    Unity的RenderTexture默认不会生成共享句柄,需要手动开启共享属性并通过Unity的DX11图形API获取句柄:

    using System;
    using System.Runtime.InteropServices;
    using UnityEngine;
    
    public class TextureShare : MonoBehaviour
    {
        [DllImport("MyNativeLib")]
        private static extern void SetBuffers11(IntPtr sharedHandle);
    
        public RenderTexture srcTexture;
    
        private void Start()
        {
            // 确保RenderTexture开启共享标志
            srcTexture.creationFlags = RenderTextureCreationFlags.Shared;
            srcTexture.Create();
    
            // 获取D3D11纹理的共享句柄
            IntPtr nativeTexPtr = srcTexture.GetNativeTexturePtr();
            IntPtr sharedHandle = IntPtr.Zero;
            NativeMethods.UnityGraphicsD3D11GetSharedHandle(nativeTexPtr, ref sharedHandle);
            
            if (sharedHandle != IntPtr.Zero)
            {
                SetBuffers11(sharedHandle);
            }
        }
    }
    
    internal static class NativeMethods
    {
        [DllImport("UnityGraphicsD3D11")]
        public static extern int UnityGraphicsD3D11GetSharedHandle(IntPtr d3dResource, ref IntPtr outSharedHandle);
    }
    
  2. C++ DLL端修改代码:
    接收共享句柄,调用OpenSharedResource1打开共享资源:

    void SetBuffers11(HANDLE sharedHandle)
    {
        if (!sharedHandle)
        {
            return;
        }
    
        ID3D11Resource* tempResource = nullptr;
        HRESULT openResult = m_device->OpenSharedResource1(
            sharedHandle, __uuidof(ID3D11Resource), (void**)&tempResource);
    
        if (SUCCEEDED(openResult))
        {
            ID3D11Texture2D* tempColor = nullptr;
            tempResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&tempColor);
            
            if (tempColor)
            {
                D3D11_TEXTURE2D_DESC texDesc;
                tempColor->GetDesc(&texDesc);
                // 后续可创建ShaderResourceView等访问纹理数据
                
                tempColor->Release();
            }
            tempResource->Release();
        }
    }
    

额外注意事项

  • 确保Unity的D3D设备和DLL的D3D设备共享同一适配器(Adapter),否则无法跨设备共享资源。创建DLL的D3D设备时,可复用Unity的适配器信息,或开启D3D11_CREATE_DEVICE_BGRA_SUPPORT等必要标志。
  • 目标纹理为TYPELESS格式,后续创建ShaderResourceView时需指定具体格式(如DXGI_FORMAT_R16G16B16A16_FLOAT)。
  • 严格管理COM对象的释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者molnarriso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:25:48