[Mesa-dev] [PATCH 60/75] st/nine: Implement {Set/Get/Free}PrivateData in iunknown

Axel Davy axel.davy at ens.fr
Wed Oct 5 20:09:33 UTC 2016


From: Patrick Rudolph <siro at das-labor.org>

Implement {Set/Get/Free}PrivateData in iunknown to get rid
of duplicated code in resource9 and volume9.

Signed-off-by: Patrick Rudolph <siro at das-labor.org>
Reviewed-by: Axel Davy <axel.davy at ens.fr>
---
 src/gallium/state_trackers/nine/iunknown.c | 114 +++++++++++++++++++++++++++++
 src/gallium/state_trackers/nine/iunknown.h |  20 +++++
 2 files changed, 134 insertions(+)

diff --git a/src/gallium/state_trackers/nine/iunknown.c b/src/gallium/state_trackers/nine/iunknown.c
index 89b82ea..541c528 100644
--- a/src/gallium/state_trackers/nine/iunknown.c
+++ b/src/gallium/state_trackers/nine/iunknown.c
@@ -22,7 +22,10 @@
 
 #include "iunknown.h"
 #include "util/u_atomic.h"
+#include "util/u_hash_table.h"
+
 #include "nine_helpers.h"
+#include "nine_pdata.h"
 
 #define DBG_CHANNEL DBG_UNKNOWN
 
@@ -43,6 +46,10 @@ NineUnknown_ctor( struct NineUnknown *This,
     This->guids = pParams->guids;
     This->dtor = pParams->dtor;
 
+    This->pdata = util_hash_table_create(ht_guid_hash, ht_guid_compare);
+    if (!This->pdata)
+        return E_OUTOFMEMORY;
+
     return D3D_OK;
 }
 
@@ -51,6 +58,12 @@ NineUnknown_dtor( struct NineUnknown *This )
 {
     if (This->refs && This->device) /* Possible only if early exit after a ctor failed */
         (void) NineUnknown_Release(NineUnknown(This->device));
+
+    if (This->pdata) {
+        util_hash_table_foreach(This->pdata, ht_guid_delete, NULL);
+        util_hash_table_destroy(This->pdata);
+    }
+
     FREE(This);
 }
 
@@ -134,3 +147,104 @@ NineUnknown_GetDevice( struct NineUnknown *This,
     *ppDevice = (IDirect3DDevice9 *)This->device;
     return D3D_OK;
 }
+
+HRESULT NINE_WINAPI
+NineUnknown_SetPrivateData( struct NineUnknown *This,
+                            REFGUID refguid,
+                            const void *pData,
+                            DWORD SizeOfData,
+                            DWORD Flags )
+{
+    enum pipe_error err;
+    struct pheader *header;
+    const void *user_data = pData;
+    char guid_str[64];
+
+    DBG("This=%p GUID=%s pData=%p SizeOfData=%u Flags=%x\n",
+        This, GUID_sprintf(guid_str, refguid), pData, SizeOfData, Flags);
+
+    if (Flags & D3DSPD_IUNKNOWN)
+        user_assert(SizeOfData == sizeof(IUnknown *), D3DERR_INVALIDCALL);
+
+    /* data consists of a header and the actual data. avoiding 2 mallocs */
+    header = CALLOC_VARIANT_LENGTH_STRUCT(pheader, SizeOfData-1);
+    if (!header) { return E_OUTOFMEMORY; }
+    header->unknown = (Flags & D3DSPD_IUNKNOWN) ? TRUE : FALSE;
+
+    /* if the refguid already exists, delete it */
+    NineUnknown_FreePrivateData(This, refguid);
+
+    /* IUnknown special case */
+    if (header->unknown) {
+        /* here the pointer doesn't point to the data we want, so point at the
+         * pointer making what we eventually copy is the pointer itself */
+        user_data = &pData;
+    }
+
+    header->size = SizeOfData;
+    memcpy(header->data, user_data, header->size);
+    memcpy(&header->guid, refguid, sizeof(header->guid));
+
+    err = util_hash_table_set(This->pdata, &header->guid, header);
+    if (err == PIPE_OK) {
+        if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); }
+        return D3D_OK;
+    }
+
+    FREE(header);
+    if (err == PIPE_ERROR_OUT_OF_MEMORY) { return E_OUTOFMEMORY; }
+
+    return D3DERR_DRIVERINTERNALERROR;
+}
+
+HRESULT NINE_WINAPI
+NineUnknown_GetPrivateData( struct NineUnknown *This,
+                            REFGUID refguid,
+                            void *pData,
+                            DWORD *pSizeOfData )
+{
+    struct pheader *header;
+    DWORD sizeofdata;
+    char guid_str[64];
+
+    DBG("This=%p GUID=%s pData=%p pSizeOfData=%p\n",
+        This, GUID_sprintf(guid_str, refguid), pData, pSizeOfData);
+
+    header = util_hash_table_get(This->pdata, refguid);
+    if (!header) { return D3DERR_NOTFOUND; }
+
+    user_assert(pSizeOfData, E_POINTER);
+    sizeofdata = *pSizeOfData;
+    *pSizeOfData = header->size;
+
+    if (!pData) {
+        return D3D_OK;
+    }
+    if (sizeofdata < header->size) {
+        return D3DERR_MOREDATA;
+    }
+
+    if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); }
+    memcpy(pData, header->data, header->size);
+
+    return D3D_OK;
+}
+
+HRESULT NINE_WINAPI
+NineUnknown_FreePrivateData( struct NineUnknown *This,
+                             REFGUID refguid )
+{
+    struct pheader *header;
+    char guid_str[64];
+
+    DBG("This=%p GUID=%s\n", This, GUID_sprintf(guid_str, refguid));
+
+    header = util_hash_table_get(This->pdata, refguid);
+    if (!header)
+        return D3DERR_NOTFOUND;
+
+    ht_guid_delete(NULL, header, NULL);
+    util_hash_table_remove(This->pdata, refguid);
+
+    return D3D_OK;
+}
diff --git a/src/gallium/state_trackers/nine/iunknown.h b/src/gallium/state_trackers/nine/iunknown.h
index bcd0b8b..63b16bd 100644
--- a/src/gallium/state_trackers/nine/iunknown.h
+++ b/src/gallium/state_trackers/nine/iunknown.h
@@ -53,6 +53,9 @@ struct NineUnknown
 
     const GUID **guids; /* for QueryInterface */
 
+    /* for [GS]etPrivateData/FreePrivateData */
+    struct util_hash_table *pdata;
+
     void (*dtor)(void *data); /* top-level dtor */
 };
 static inline struct NineUnknown *
@@ -95,6 +98,23 @@ HRESULT NINE_WINAPI
 NineUnknown_GetDevice( struct NineUnknown *This,
                        IDirect3DDevice9 **ppDevice );
 
+HRESULT NINE_WINAPI
+NineUnknown_SetPrivateData( struct NineUnknown *This,
+                            REFGUID refguid,
+                            const void *pData,
+                            DWORD SizeOfData,
+                            DWORD Flags );
+
+HRESULT NINE_WINAPI
+NineUnknown_GetPrivateData( struct NineUnknown *This,
+                            REFGUID refguid,
+                            void *pData,
+                            DWORD *pSizeOfData );
+
+HRESULT NINE_WINAPI
+NineUnknown_FreePrivateData( struct NineUnknown *This,
+                             REFGUID refguid );
+
 /*** Nine private methods ***/
 
 static inline void
-- 
2.10.0



More information about the mesa-dev mailing list