win32: Add GdkD3D12TextureBuilder::fence
Add ::fence and ::fence-wait to set the fence and the value to wait for. And wait for it before download()ing.
This commit is contained in:
@@ -49,6 +49,9 @@ struct _GdkD3D12Texture
|
||||
|
||||
ID3D12Resource *resource;
|
||||
HANDLE resource_handle;
|
||||
ID3D12Fence *fence;
|
||||
HANDLE fence_handle;
|
||||
guint64 fence_wait;
|
||||
|
||||
GDestroyNotify destroy;
|
||||
gpointer data;
|
||||
@@ -75,18 +78,27 @@ gdk_d3d12_texture_dispose (GObject *object)
|
||||
{
|
||||
GdkD3D12Texture *self = GDK_D3D12_TEXTURE (object);
|
||||
|
||||
if (self->fence_handle)
|
||||
{
|
||||
if (G_UNLIKELY (!CloseHandle (self->fence_handle)))
|
||||
{
|
||||
g_warning ("Failed to fence handle: %s", g_win32_error_message (GetLastError ()));
|
||||
}
|
||||
self->fence_handle = NULL;
|
||||
}
|
||||
if (self->resource_handle)
|
||||
{
|
||||
if (G_UNLIKELY (!CloseHandle (self->resource_handle)))
|
||||
{
|
||||
g_warning ("Failed to close handle: %s", g_win32_error_message (GetLastError ()));
|
||||
g_warning ("Failed to close resource handle: %s", g_win32_error_message (GetLastError ()));
|
||||
}
|
||||
self->resource_handle = NULL;
|
||||
}
|
||||
|
||||
gdk_win32_com_clear (&self->fence);
|
||||
gdk_win32_com_clear (&self->resource);
|
||||
|
||||
if (self->destroy)
|
||||
if (self->destroy)
|
||||
{
|
||||
self->destroy (self->data);
|
||||
self->destroy = NULL;
|
||||
@@ -222,6 +234,10 @@ gdk_d3d12_texture_download (GdkTexture *texture,
|
||||
}),
|
||||
NULL);
|
||||
hr_return_if_fail (ID3D12GraphicsCommandList_Close (commands));
|
||||
|
||||
if (self->fence)
|
||||
ID3D12CommandQueue_Wait (queue, self->fence, self->fence_wait);
|
||||
|
||||
ID3D12CommandQueue_ExecuteCommandLists (queue, 1, (ID3D12CommandList **) &commands);
|
||||
|
||||
#define FENCE_SIGNAL 1
|
||||
@@ -285,10 +301,12 @@ gdk_d3d12_texture_new_from_builder (GdkD3D12TextureBuilder *builder,
|
||||
GdkColorState *color_state;
|
||||
GdkMemoryFormat format;
|
||||
ID3D12Resource *resource;
|
||||
ID3D12Fence *fence;
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
gboolean premultiplied;
|
||||
|
||||
resource = gdk_d3d12_texture_builder_get_resource (builder);
|
||||
fence = gdk_d3d12_texture_builder_get_fence (builder);
|
||||
premultiplied = gdk_d3d12_texture_builder_get_premultiplied (builder);
|
||||
ID3D12Resource_GetDesc (resource, &desc);
|
||||
|
||||
@@ -325,6 +343,12 @@ gdk_d3d12_texture_new_from_builder (GdkD3D12TextureBuilder *builder,
|
||||
GDK_TEXTURE (self)->format = format;
|
||||
ID3D12Resource_AddRef (resource);
|
||||
self->resource = resource;
|
||||
if (fence)
|
||||
{
|
||||
ID3D12Fence_AddRef (fence);
|
||||
self->fence = fence;
|
||||
self->fence_wait = gdk_d3d12_texture_builder_get_fence_wait (builder);
|
||||
}
|
||||
|
||||
GDK_DEBUG (D3D12,
|
||||
"Creating %ux%u D3D12 texture, format %u",
|
||||
|
||||
@@ -33,6 +33,8 @@ struct _GdkD3D12TextureBuilder
|
||||
GObject parent_instance;
|
||||
|
||||
ID3D12Resource *resource;
|
||||
ID3D12Fence *fence;
|
||||
guint64 fence_wait;
|
||||
|
||||
GdkColorState *color_state;
|
||||
gboolean premultiplied;
|
||||
@@ -69,6 +71,8 @@ enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_COLOR_STATE,
|
||||
PROP_FENCE,
|
||||
PROP_FENCE_WAIT,
|
||||
PROP_RESOURCE,
|
||||
PROP_PREMULTIPLIED,
|
||||
PROP_UPDATE_REGION,
|
||||
@@ -91,6 +95,7 @@ gdk_d3d12_texture_builder_dispose (GObject *object)
|
||||
g_clear_pointer (&self->color_state, gdk_color_state_unref);
|
||||
|
||||
gdk_win32_com_clear (&self->resource);
|
||||
gdk_win32_com_clear (&self->fence);
|
||||
|
||||
G_OBJECT_CLASS (gdk_d3d12_texture_builder_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -109,6 +114,14 @@ gdk_d3d12_texture_builder_get_property (GObject *object,
|
||||
g_value_set_boxed (value, self->color_state);
|
||||
break;
|
||||
|
||||
case PROP_FENCE:
|
||||
g_value_set_pointer (value, self->fence);
|
||||
break;
|
||||
|
||||
case PROP_FENCE_WAIT:
|
||||
g_value_set_uint64 (value, self->fence_wait);
|
||||
break;
|
||||
|
||||
case PROP_PREMULTIPLIED:
|
||||
g_value_set_boolean (value, self->premultiplied);
|
||||
break;
|
||||
@@ -145,6 +158,14 @@ gdk_d3d12_texture_builder_set_property (GObject *object,
|
||||
gdk_d3d12_texture_builder_set_color_state (self, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_FENCE:
|
||||
gdk_d3d12_texture_builder_set_fence (self, g_value_get_pointer (value));
|
||||
break;
|
||||
|
||||
case PROP_FENCE_WAIT:
|
||||
gdk_d3d12_texture_builder_set_fence_wait (self, g_value_get_uint64 (value));
|
||||
break;
|
||||
|
||||
case PROP_PREMULTIPLIED:
|
||||
gdk_d3d12_texture_builder_set_premultiplied (self, g_value_get_boolean (value));
|
||||
break;
|
||||
@@ -188,6 +209,29 @@ gdk_d3d12_texture_builder_class_init (GdkD3D12TextureBuilderClass *klass)
|
||||
GDK_TYPE_COLOR_STATE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkD3D12TextureBuilder:fence:
|
||||
*
|
||||
* The optional `ID3D12Fence` to wait on before using the resource.
|
||||
*
|
||||
* Since: 4.18
|
||||
*/
|
||||
properties[PROP_FENCE] =
|
||||
g_param_spec_pointer ("fence", NULL, NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkD3D12TextureBuilder:fence-wait:
|
||||
*
|
||||
* The value the fence should wait on
|
||||
*
|
||||
* Since: 4.18
|
||||
*/
|
||||
properties[PROP_FENCE_WAIT] =
|
||||
g_param_spec_uint64 ("fence-wait", NULL, NULL,
|
||||
0, G_MAXUINT64, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkD3D12TextureBuilder:premultiplied:
|
||||
*
|
||||
@@ -308,6 +352,97 @@ gdk_d3d12_texture_builder_set_resource (GdkD3D12TextureBuilder *self,
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RESOURCE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_d3d12_texture_builder_get_fence:
|
||||
* @self: a `GdkD3D12TextureBuilder`
|
||||
*
|
||||
* Returns the fence that this texture builder is
|
||||
* associated with.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the fence
|
||||
*
|
||||
* Since: 4.18
|
||||
*/
|
||||
ID3D12Fence *
|
||||
gdk_d3d12_texture_builder_get_fence (GdkD3D12TextureBuilder *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_D3D12_TEXTURE_BUILDER (self), NULL);
|
||||
|
||||
return self->fence;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_d3d12_texture_builder_set_fence:
|
||||
* @self: a `GdkD3D12TextureBuilder`
|
||||
* @fence: the fence
|
||||
*
|
||||
* Sets the fence that this texture builder is going to construct
|
||||
* a texture for.
|
||||
*
|
||||
* Since: 4.18
|
||||
*/
|
||||
void
|
||||
gdk_d3d12_texture_builder_set_fence (GdkD3D12TextureBuilder *self,
|
||||
ID3D12Fence *fence)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_D3D12_TEXTURE_BUILDER (self));
|
||||
|
||||
if (self->fence == fence)
|
||||
return;
|
||||
|
||||
if (fence)
|
||||
ID3D12Fence_AddRef (fence);
|
||||
gdk_win32_com_clear (&self->fence);
|
||||
self->fence = fence;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FENCE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_d3d12_texture_builder_get_fence_wait:
|
||||
* @self: a `GdkD3D12TextureBuilder`
|
||||
*
|
||||
* Returns the value that GTK should wait for on the fence
|
||||
* before using the resource.
|
||||
*
|
||||
* Returns: the fence wait value
|
||||
*
|
||||
* Since: 4.18
|
||||
*/
|
||||
guint64
|
||||
gdk_d3d12_texture_builder_get_fence_wait (GdkD3D12TextureBuilder *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_D3D12_TEXTURE_BUILDER (self), 0);
|
||||
|
||||
return self->fence_wait;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_d3d12_texture_builder_set_fence_wait:
|
||||
* @self: a `GdkD3D12TextureBuilder`
|
||||
* @fence_wait: the value to wait on
|
||||
*
|
||||
* Sets the value that GTK should wait on on the given fence before using the
|
||||
* resource.
|
||||
*
|
||||
* When no fence is set, this value has no effect.
|
||||
*
|
||||
* Since: 4.18
|
||||
*/
|
||||
void
|
||||
gdk_d3d12_texture_builder_set_fence_wait (GdkD3D12TextureBuilder *self,
|
||||
guint64 fence_wait)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_D3D12_TEXTURE_BUILDER (self));
|
||||
|
||||
if (self->fence_wait == fence_wait)
|
||||
return;
|
||||
|
||||
self->fence_wait = fence_wait;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FENCE_WAIT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_d3d12_texture_builder_get_premultiplied:
|
||||
* @self: a `GdkD3D12TextureBuilder`
|
||||
|
||||
@@ -43,7 +43,19 @@ ID3D12Resource * gdk_d3d12_texture_builder_get_resource (GdkD3D1
|
||||
GDK_AVAILABLE_IN_4_18
|
||||
void gdk_d3d12_texture_builder_set_resource (GdkD3D12TextureBuilder *self,
|
||||
ID3D12Resource *resource);
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_4_18
|
||||
ID3D12Fence * gdk_d3d12_texture_builder_get_fence (GdkD3D12TextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_18
|
||||
void gdk_d3d12_texture_builder_set_fence (GdkD3D12TextureBuilder *self,
|
||||
ID3D12Fence *fence);
|
||||
|
||||
GDK_AVAILABLE_IN_4_18
|
||||
guint64 gdk_d3d12_texture_builder_get_fence_wait (GdkD3D12TextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_18
|
||||
void gdk_d3d12_texture_builder_set_fence_wait (GdkD3D12TextureBuilder *self,
|
||||
guint64 fence_wait);
|
||||
|
||||
GDK_AVAILABLE_IN_4_18
|
||||
gboolean gdk_d3d12_texture_builder_get_premultiplied (GdkD3D12TextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_18
|
||||
|
||||
Reference in New Issue
Block a user