From cf2be60a67521dd98037c014fe8e583e5848d272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Mon, 24 Sep 2018 17:34:07 +0200 Subject: [PATCH] vrclient: Implement LoadIntoTextureD3D11_Async(). --- vrclient_x64/gen_wrapper.py | 5 ++ vrclient_x64/vrclient_x64/vrclient_defs.h | 8 +- vrclient_x64/vrclient_x64/vrclient_main.c | 88 +++++++++++++++++++ vrclient_x64/vrclient_x64/vrclient_private.h | 5 ++ .../vrclient_x64/winIVRRenderModels.c | 2 +- 5 files changed, 106 insertions(+), 2 deletions(-) diff --git a/vrclient_x64/gen_wrapper.py b/vrclient_x64/gen_wrapper.py index 6a4f71b1..9735af22 100755 --- a/vrclient_x64/gen_wrapper.py +++ b/vrclient_x64/gen_wrapper.py @@ -177,6 +177,10 @@ def ivrcompositor_wait_get_poses(cppname, method): def ivrcompositor_get_vulkan_device_extensions_required(cppname, method): return "ivrcompositor_get_vulkan_device_extensions_required" +def ivrrendermodels_load_into_texture_d3d11_async(cppname, method): + assert "005" in cppname + return "ivrrendermodels_load_into_texture_d3d11_async" + method_overrides = [ ("IVRClientCore", "Init", ivrclientcore_init), ("IVRClientCore", "GetGenericInterface", ivrclientcore_get_generic_interface), @@ -187,6 +191,7 @@ method_overrides = [ ("IVRCompositor", "PostPresentHandoff", ivrcompositor_post_present_handoff), ("IVRCompositor", "WaitGetPoses", ivrcompositor_wait_get_poses), ("IVRCompositor", "GetVulkanDeviceExtensionsRequired", ivrcompositor_get_vulkan_device_extensions_required), + ("IVRRenderModels", "LoadIntoTextureD3D11_Async", ivrrendermodels_load_into_texture_d3d11_async), ] method_overrides_data = [ diff --git a/vrclient_x64/vrclient_x64/vrclient_defs.h b/vrclient_x64/vrclient_x64/vrclient_defs.h index 7ae7aead..add4925d 100644 --- a/vrclient_x64/vrclient_x64/vrclient_defs.h +++ b/vrclient_x64/vrclient_x64/vrclient_defs.h @@ -19,7 +19,6 @@ typedef int EVRInitError, EVRApplicationType, EVRButtonId, - EVRRenderModelError, EVRCompositorError, EVRApplicationError, EVRApplicationProperty, @@ -286,4 +285,11 @@ typedef enum EVRCompositorTimingMode VRCompositorTimingMode_Explicit_ApplicationPerformsPostPresentHandoff = 2, } EVRCompositorTimingMode; +typedef enum EVRRenderModelError +{ + VRRenderModelError_None = 0, + VRRenderModelError_Loading = 100, + VRRenderModelError_NotSupported = 200, +} EVRRenderModelError; + #endif diff --git a/vrclient_x64/vrclient_x64/vrclient_main.c b/vrclient_x64/vrclient_x64/vrclient_main.c index 819311f1..0fc03b09 100644 --- a/vrclient_x64/vrclient_x64/vrclient_main.c +++ b/vrclient_x64/vrclient_x64/vrclient_main.c @@ -28,6 +28,11 @@ #include "cppIVRCompositor_IVRCompositor_021.h" #include "cppIVRCompositor_IVRCompositor_022.h" +typedef struct winRenderModel_t_1015 winRenderModel_t_1015; +typedef struct winRenderModel_TextureMap_t_1015 winRenderModel_TextureMap_t_1015; + +#include "cppIVRRenderModels_IVRRenderModels_005.h" + WINE_DEFAULT_DEBUG_CHANNEL(vrclient); BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) @@ -946,6 +951,89 @@ uint32_t ivrcompositor_get_vulkan_device_extensions_required( return cpp_func(linux_side, phys_dev, value, bufsize); } +struct winRenderModel_TextureMap_t_1015 { + uint16_t unWidth; + uint16_t unHeight; + const uint8_t *rubTextureMapData; +} __attribute__ ((ms_struct)); + +static EVRRenderModelError load_into_texture_d3d11(ID3D11Texture2D *texture, + const struct winRenderModel_TextureMap_t_1015 *data) +{ + D3D11_TEXTURE2D_DESC texture_desc; + ID3D11DeviceContext *context; + ID3D11Device *device; + + texture->lpVtbl->GetDesc(texture, &texture_desc); + + TRACE("Format %#x, width %u, height %u.\n", + texture_desc.Format, texture_desc.Width, texture_desc.Height); + TRACE("Array size %u, miplevels %u.\n", + texture_desc.ArraySize, texture_desc.MipLevels); + + if (texture_desc.Format != DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) + { + FIXME("Unexpected format %#x.\n", texture_desc.Format); + return VRRenderModelError_NotSupported; + } + if (texture_desc.Width != data->unWidth) + { + FIXME("Unexpected width %u.\n", texture_desc.Width); + return VRRenderModelError_NotSupported; + } + if (texture_desc.Height != data->unHeight) + { + FIXME("Unexpected height %u.\n", texture_desc.Height); + return VRRenderModelError_NotSupported; + } + + texture->lpVtbl->GetDevice(texture, &device); + device->lpVtbl->GetImmediateContext(device, &context); + device->lpVtbl->Release(device); + + context->lpVtbl->UpdateSubresource(context, (ID3D11Resource *)texture, + 0, NULL, data->rubTextureMapData, data->unWidth * 4 * sizeof(uint8_t), 0); + + context->lpVtbl->Release(context); + return VRRenderModelError_None; +} + +EVRRenderModelError ivrrendermodels_load_into_texture_d3d11_async( + EVRRenderModelError (*cpp_func)(void *, TextureID_t, void *), + void *linux_side, TextureID_t texture_id, void *dst_texture, unsigned int version) +{ + struct winRenderModel_TextureMap_t_1015 *texture_map; + IUnknown *unk = dst_texture; + EVRRenderModelError error; + ID3D11Texture2D *texture; + + error = cppIVRRenderModels_IVRRenderModels_005_LoadTexture_Async(linux_side, texture_id, &texture_map); + if (error == VRRenderModelError_Loading) + { + TRACE("Loading.\n"); + return error; + } + if (error != VRRenderModelError_None) + { + WARN("Failed to load texture %#x.\n", error); + return error; + } + + if (SUCCEEDED(unk->lpVtbl->QueryInterface(unk, &IID_ID3D11Texture2D, (void **)&texture))) + { + error = load_into_texture_d3d11(texture, texture_map); + texture->lpVtbl->Release(texture); + } + else + { + FIXME("Expected 2D texture.\n"); + error = VRRenderModelError_NotSupported; + } + + cppIVRRenderModels_IVRRenderModels_005_FreeTexture(linux_side, texture_map); + return error; +} + void destroy_compositor_data(struct compositor_data *data) { IWineD3D11Device *wined3d_device; diff --git a/vrclient_x64/vrclient_x64/vrclient_private.h b/vrclient_x64/vrclient_x64/vrclient_private.h index 18910225..6dbd4863 100644 --- a/vrclient_x64/vrclient_x64/vrclient_private.h +++ b/vrclient_x64/vrclient_x64/vrclient_private.h @@ -132,6 +132,11 @@ uint32_t ivrcompositor_get_vulkan_device_extensions_required( uint32_t (*cpp_func)(void *, VkPhysicalDevice_T *, char *, uint32_t), void *linux_side, VkPhysicalDevice_T *phys_dev, char *value, uint32_t bufsize, unsigned int version, struct compositor_data *user_data); + +EVRRenderModelError ivrrendermodels_load_into_texture_d3d11_async( + EVRRenderModelError (*cpp_func)(void *, TextureID_t, void *), + void *linux_side, TextureID_t texture_id, void *dst_texture, unsigned int version); + #endif /* __cplusplus */ #define TRACE WINE_TRACE diff --git a/vrclient_x64/vrclient_x64/winIVRRenderModels.c b/vrclient_x64/vrclient_x64/winIVRRenderModels.c index aa1689ec..1b364e8d 100644 --- a/vrclient_x64/vrclient_x64/winIVRRenderModels.c +++ b/vrclient_x64/vrclient_x64/winIVRRenderModels.c @@ -64,7 +64,7 @@ DEFINE_THISCALL_WRAPPER(winIVRRenderModels_IVRRenderModels_005_LoadIntoTextureD3 EVRRenderModelError __thiscall winIVRRenderModels_IVRRenderModels_005_LoadIntoTextureD3D11_Async(winIVRRenderModels_IVRRenderModels_005 *_this, TextureID_t textureId, void * pDstTexture) { TRACE("%p\n", _this); - return cppIVRRenderModels_IVRRenderModels_005_LoadIntoTextureD3D11_Async(_this->linux_side, textureId, pDstTexture); + return ivrrendermodels_load_into_texture_d3d11_async(cppIVRRenderModels_IVRRenderModels_005_LoadIntoTextureD3D11_Async, _this->linux_side, textureId, pDstTexture, 5); } DEFINE_THISCALL_WRAPPER(winIVRRenderModels_IVRRenderModels_005_FreeTextureD3D11, 12)