mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-06 07:28:48 +00:00
d3d12converter: Gamma LUT related enhancements
* Build gamma LUT using shader, instead of CPU side math then uploading * Make gamma LUT sharable across multiple converters Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7951>
This commit is contained in:
parent
f3191aca58
commit
6bcedb0d8b
3 changed files with 476 additions and 229 deletions
|
@ -166,14 +166,7 @@ struct VertexData
|
||||||
} texture;
|
} texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GammaLut
|
|
||||||
{
|
|
||||||
guint16 lut[GAMMA_LUT_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
typedef std::shared_ptr<GammaLut> GammaLutPtr;
|
|
||||||
|
|
||||||
static const XMFLOAT4X4A g_matrix_identity = XMFLOAT4X4A (
|
static const XMFLOAT4X4A g_matrix_identity = XMFLOAT4X4A (
|
||||||
1.0f, 0.0f, 0.0f, 0.0f,
|
1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
0.0f, 1.0f, 0.0f, 0.0f,
|
0.0f, 1.0f, 0.0f, 0.0f,
|
||||||
|
@ -293,6 +286,12 @@ struct _GstD3D12ConverterPrivate
|
||||||
if (fence_val > 0 && cq)
|
if (fence_val > 0 && cq)
|
||||||
gst_d3d12_cmd_queue_fence_wait (cq, fence_val);
|
gst_d3d12_cmd_queue_fence_wait (cq, fence_val);
|
||||||
|
|
||||||
|
if (setup_fence) {
|
||||||
|
auto completed = setup_fence->GetCompletedValue ();
|
||||||
|
if (completed < setup_fence_val)
|
||||||
|
setup_fence->SetEventOnCompletion (setup_fence_val, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
gst_clear_object (&srv_heap_pool);
|
gst_clear_object (&srv_heap_pool);
|
||||||
gst_clear_object (&cq);
|
gst_clear_object (&cq);
|
||||||
gst_clear_object (&pack);
|
gst_clear_object (&pack);
|
||||||
|
@ -323,7 +322,7 @@ struct _GstD3D12ConverterPrivate
|
||||||
gboolean have_lut = FALSE;
|
gboolean have_lut = FALSE;
|
||||||
|
|
||||||
D3D12_VERTEX_BUFFER_VIEW vbv;
|
D3D12_VERTEX_BUFFER_VIEW vbv;
|
||||||
D3D12_INDEX_BUFFER_VIEW idv;
|
D3D12_INDEX_BUFFER_VIEW ibv;
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS const_buf_addr[2];
|
D3D12_GPU_VIRTUAL_ADDRESS const_buf_addr[2];
|
||||||
ComPtr<ID3D12Resource> shader_buf;
|
ComPtr<ID3D12Resource> shader_buf;
|
||||||
ComPtr<ID3D12Resource> vertex_upload;
|
ComPtr<ID3D12Resource> vertex_upload;
|
||||||
|
@ -360,6 +359,9 @@ struct _GstD3D12ConverterPrivate
|
||||||
std::mutex prop_lock;
|
std::mutex prop_lock;
|
||||||
guint64 fence_val = 0;
|
guint64 fence_val = 0;
|
||||||
|
|
||||||
|
ComPtr<ID3D12Fence> setup_fence;
|
||||||
|
guint64 setup_fence_val = 0;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
gint src_x = 0;
|
gint src_x = 0;
|
||||||
gint src_y = 0;
|
gint src_y = 0;
|
||||||
|
@ -695,54 +697,6 @@ gst_d3d12_converter_get_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GammaLutPtr
|
|
||||||
gst_d3d12_converter_get_gamma_dec_table (GstVideoTransferFunction func)
|
|
||||||
{
|
|
||||||
static std::mutex lut_lock;
|
|
||||||
static std::map < GstVideoTransferFunction, GammaLutPtr > g_gamma_dec_table;
|
|
||||||
|
|
||||||
std::lock_guard < std::mutex > lk (lut_lock);
|
|
||||||
auto lut = g_gamma_dec_table.find (func);
|
|
||||||
if (lut != g_gamma_dec_table.end ())
|
|
||||||
return lut->second;
|
|
||||||
|
|
||||||
const gdouble scale = (gdouble) 1 / (GAMMA_LUT_SIZE - 1);
|
|
||||||
auto table = std::make_shared < GammaLut > ();
|
|
||||||
for (guint i = 0; i < GAMMA_LUT_SIZE; i++) {
|
|
||||||
gdouble val = gst_video_transfer_function_decode (func, i * scale);
|
|
||||||
val = rint (val * 65535);
|
|
||||||
val = CLAMP (val, 0, 65535);
|
|
||||||
table->lut[i] = (guint16) val;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_gamma_dec_table[func] = table;
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GammaLutPtr
|
|
||||||
gst_d3d12_converter_get_gamma_enc_table (GstVideoTransferFunction func)
|
|
||||||
{
|
|
||||||
static std::mutex lut_lock;
|
|
||||||
static std::map < GstVideoTransferFunction, GammaLutPtr > g_gamma_enc_table;
|
|
||||||
|
|
||||||
std::lock_guard < std::mutex > lk (lut_lock);
|
|
||||||
auto lut = g_gamma_enc_table.find (func);
|
|
||||||
if (lut != g_gamma_enc_table.end ())
|
|
||||||
return lut->second;
|
|
||||||
|
|
||||||
const gdouble scale = (gdouble) 1 / (GAMMA_LUT_SIZE - 1);
|
|
||||||
auto table = std::make_shared < GammaLut > ();
|
|
||||||
for (guint i = 0; i < GAMMA_LUT_SIZE; i++) {
|
|
||||||
gdouble val = gst_video_transfer_function_encode (func, i * scale);
|
|
||||||
val = rint (val * 65535);
|
|
||||||
val = CLAMP (val, 0, 65535);
|
|
||||||
table->lut[i] = (guint16) val;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_gamma_enc_table[func] = table;
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
reorder_rtv_index (GstVideoFormat output_format, guint index)
|
reorder_rtv_index (GstVideoFormat output_format, guint index)
|
||||||
{
|
{
|
||||||
|
@ -820,8 +774,6 @@ gst_d3d12_converter_setup_resource (GstD3D12Converter * self,
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
VertexData vertex_data[4];
|
VertexData vertex_data[4];
|
||||||
ComPtr < ID3D12Resource > upload_buf;
|
ComPtr < ID3D12Resource > upload_buf;
|
||||||
ComPtr < ID3D12Resource > gamma_dec_lut_upload;
|
|
||||||
ComPtr < ID3D12Resource > gamma_enc_lut_upload;
|
|
||||||
|
|
||||||
auto device = gst_d3d12_device_get_device_handle (self->device);
|
auto device = gst_d3d12_device_get_device_handle (self->device);
|
||||||
|
|
||||||
|
@ -1023,9 +975,9 @@ gst_d3d12_converter_setup_resource (GstD3D12Converter * self,
|
||||||
priv->vbv.SizeInBytes = g_vertex_buf_size;
|
priv->vbv.SizeInBytes = g_vertex_buf_size;
|
||||||
priv->vbv.StrideInBytes = sizeof (VertexData);
|
priv->vbv.StrideInBytes = sizeof (VertexData);
|
||||||
|
|
||||||
priv->idv.BufferLocation = priv->vbv.BufferLocation + g_vertex_buf_size;
|
priv->ibv.BufferLocation = priv->vbv.BufferLocation + g_vertex_buf_size;
|
||||||
priv->idv.SizeInBytes = g_index_buf_size;
|
priv->ibv.SizeInBytes = g_index_buf_size;
|
||||||
priv->idv.Format = DXGI_FORMAT_R16_UINT;
|
priv->ibv.Format = DXGI_FORMAT_R16_UINT;
|
||||||
|
|
||||||
priv->const_buf_addr[0] = priv->vbv.BufferLocation + vertex_index_size;
|
priv->const_buf_addr[0] = priv->vbv.BufferLocation + vertex_index_size;
|
||||||
priv->const_buf_addr[1] = priv->vbv.BufferLocation + other_const_off;
|
priv->const_buf_addr[1] = priv->vbv.BufferLocation + other_const_off;
|
||||||
|
@ -1053,50 +1005,6 @@ gst_d3d12_converter_setup_resource (GstD3D12Converter * self,
|
||||||
upload_buf->Unmap (0, nullptr);
|
upload_buf->Unmap (0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->have_lut) {
|
|
||||||
heap_prop = CD3DX12_HEAP_PROPERTIES (D3D12_HEAP_TYPE_DEFAULT);
|
|
||||||
resource_desc = CD3DX12_RESOURCE_DESC::Tex1D (DXGI_FORMAT_R16_UNORM,
|
|
||||||
GAMMA_LUT_SIZE, 1, 1);
|
|
||||||
|
|
||||||
hr = device->CreateCommittedResource (&heap_prop,
|
|
||||||
heap_flags, &resource_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
|
|
||||||
IID_PPV_ARGS (&priv->gamma_dec_lut));
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't create gamma decoding LUT");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = device->CreateCommittedResource (&heap_prop,
|
|
||||||
heap_flags, &resource_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
|
|
||||||
IID_PPV_ARGS (&priv->gamma_enc_lut));
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't create gamma encoding LUT");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT64 gamma_lut_size;
|
|
||||||
device->GetCopyableFootprints (&resource_desc, 0, 1, 0,
|
|
||||||
&priv->gamma_lut_layout, nullptr, nullptr, &gamma_lut_size);
|
|
||||||
|
|
||||||
heap_prop = CD3DX12_HEAP_PROPERTIES (D3D12_HEAP_TYPE_UPLOAD);
|
|
||||||
resource_desc = CD3DX12_RESOURCE_DESC::Buffer (gamma_lut_size);
|
|
||||||
|
|
||||||
hr = device->CreateCommittedResource (&heap_prop,
|
|
||||||
heap_flags, &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr,
|
|
||||||
IID_PPV_ARGS (&gamma_dec_lut_upload));
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't create gamma decoding LUT upload");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = device->CreateCommittedResource (&heap_prop,
|
|
||||||
heap_flags, &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr,
|
|
||||||
IID_PPV_ARGS (&gamma_enc_lut_upload));
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't create gamma encoding LUT upload");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto in_trc = in_info->colorimetry.transfer;
|
auto in_trc = in_info->colorimetry.transfer;
|
||||||
auto out_trc = in_info->colorimetry.transfer;
|
auto out_trc = in_info->colorimetry.transfer;
|
||||||
|
|
||||||
|
@ -1105,56 +1013,6 @@ gst_d3d12_converter_setup_resource (GstD3D12Converter * self,
|
||||||
out_trc = out_info->colorimetry.transfer;
|
out_trc = out_info->colorimetry.transfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gamma_dec_table = gst_d3d12_converter_get_gamma_dec_table (in_trc);
|
|
||||||
auto gamma_enc_table = gst_d3d12_converter_get_gamma_enc_table (out_trc);
|
|
||||||
|
|
||||||
hr = gamma_dec_lut_upload->Map (0, &range, (void **) &data);
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't map gamma lut upload buffer");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (data, gamma_dec_table->lut, GAMMA_LUT_SIZE * sizeof (guint16));
|
|
||||||
gamma_dec_lut_upload->Unmap (0, nullptr);
|
|
||||||
|
|
||||||
hr = gamma_enc_lut_upload->Map (0, &range, (void **) &data);
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't map gamma lut upload buffer");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (data, gamma_enc_table->lut, GAMMA_LUT_SIZE * sizeof (guint16));
|
|
||||||
gamma_enc_lut_upload->Unmap (0, nullptr);
|
|
||||||
|
|
||||||
D3D12_DESCRIPTOR_HEAP_DESC desc = { };
|
|
||||||
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
|
||||||
desc.NumDescriptors = 2;
|
|
||||||
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
|
||||||
|
|
||||||
auto hr = device->CreateDescriptorHeap (&desc,
|
|
||||||
IID_PPV_ARGS (&priv->gamma_lut_heap));
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't map gamma lut upload buffer");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cpu_handle =
|
|
||||||
CD3DX12_CPU_DESCRIPTOR_HANDLE (GetCPUDescriptorHandleForHeapStart
|
|
||||||
(priv->gamma_lut_heap));
|
|
||||||
|
|
||||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = { };
|
|
||||||
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
|
|
||||||
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
|
||||||
srv_desc.Texture1D.MipLevels = 1;
|
|
||||||
|
|
||||||
device->CreateShaderResourceView (priv->gamma_dec_lut.Get (), &srv_desc,
|
|
||||||
cpu_handle);
|
|
||||||
cpu_handle.Offset (priv->srv_inc_size);
|
|
||||||
|
|
||||||
device->CreateShaderResourceView (priv->gamma_enc_lut.Get (), &srv_desc,
|
|
||||||
cpu_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->input_texture_width = GST_VIDEO_INFO_WIDTH (in_info);
|
priv->input_texture_width = GST_VIDEO_INFO_WIDTH (in_info);
|
||||||
priv->input_texture_height = GST_VIDEO_INFO_HEIGHT (in_info);
|
priv->input_texture_height = GST_VIDEO_INFO_HEIGHT (in_info);
|
||||||
|
|
||||||
|
@ -1172,84 +1030,52 @@ gst_d3d12_converter_setup_resource (GstD3D12Converter * self,
|
||||||
priv->scissor_rect[i].bottom = GST_VIDEO_INFO_COMP_HEIGHT (out_info, i);
|
priv->scissor_rect[i].bottom = GST_VIDEO_INFO_COMP_HEIGHT (out_info, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
ComPtr < ID3D12CommandAllocator > ca;
|
|
||||||
hr = device->CreateCommandAllocator (D3D12_COMMAND_LIST_TYPE_DIRECT,
|
|
||||||
IID_PPV_ARGS (&ca));
|
|
||||||
if (!gst_d3d12_result (hr, self->device))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
ComPtr < ID3D12GraphicsCommandList > cl;
|
|
||||||
hr = device->CreateCommandList (0, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
|
||||||
ca.Get (), nullptr, IID_PPV_ARGS (&cl));
|
|
||||||
if (!gst_d3d12_result (hr, self->device))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
std::vector < D3D12_RESOURCE_BARRIER > barriers;
|
|
||||||
cl->CopyResource (priv->shader_buf.Get (), upload_buf.Get ());
|
|
||||||
|
|
||||||
barriers.push_back (CD3DX12_RESOURCE_BARRIER::Transition (priv->shader_buf.
|
|
||||||
Get (), D3D12_RESOURCE_STATE_COPY_DEST, STATE_VERTEX_AND_INDEX));
|
|
||||||
|
|
||||||
if (priv->have_lut) {
|
if (priv->have_lut) {
|
||||||
D3D12_TEXTURE_COPY_LOCATION src;
|
hr = gst_d3d12_device_get_converter_resources (self->device,
|
||||||
D3D12_TEXTURE_COPY_LOCATION dst;
|
priv->shader_buf.Get (), upload_buf.Get (), &priv->vbv, &priv->ibv,
|
||||||
src =
|
in_trc, &priv->gamma_dec_lut, out_trc, &priv->gamma_enc_lut,
|
||||||
CD3DX12_TEXTURE_COPY_LOCATION (gamma_dec_lut_upload.Get (),
|
&priv->setup_fence, &priv->setup_fence_val);
|
||||||
priv->gamma_lut_layout);
|
} else {
|
||||||
dst = CD3DX12_TEXTURE_COPY_LOCATION (priv->gamma_dec_lut.Get ());
|
hr = gst_d3d12_device_get_converter_resources (self->device,
|
||||||
cl->CopyTextureRegion (&dst, 0, 0, 0, &src, nullptr);
|
priv->shader_buf.Get (), upload_buf.Get (), &priv->vbv, &priv->ibv,
|
||||||
|
in_trc, nullptr, out_trc, nullptr, &priv->setup_fence,
|
||||||
src =
|
&priv->setup_fence_val);
|
||||||
CD3DX12_TEXTURE_COPY_LOCATION (gamma_enc_lut_upload.Get (),
|
|
||||||
priv->gamma_lut_layout);
|
|
||||||
dst = CD3DX12_TEXTURE_COPY_LOCATION (priv->gamma_enc_lut.Get ());
|
|
||||||
cl->CopyTextureRegion (&dst, 0, 0, 0, &src, nullptr);
|
|
||||||
|
|
||||||
barriers.
|
|
||||||
push_back (CD3DX12_RESOURCE_BARRIER::Transition (priv->gamma_dec_lut.
|
|
||||||
Get (), D3D12_RESOURCE_STATE_COPY_DEST,
|
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
|
||||||
barriers.
|
|
||||||
push_back (CD3DX12_RESOURCE_BARRIER::Transition (priv->gamma_enc_lut.
|
|
||||||
Get (), D3D12_RESOURCE_STATE_COPY_DEST,
|
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cl->ResourceBarrier (barriers.size (), barriers.data ());
|
|
||||||
|
|
||||||
hr = cl->Close ();
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
|
||||||
GST_ERROR_OBJECT (self, "Couldn't close upload command list");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D12CommandList *cmd_list[] = { cl.Get () };
|
|
||||||
|
|
||||||
hr = gst_d3d12_cmd_queue_execute_command_lists (priv->cq, 1, cmd_list,
|
|
||||||
&priv->fence_val);
|
|
||||||
if (!gst_d3d12_result (hr, self->device)) {
|
if (!gst_d3d12_result (hr, self->device)) {
|
||||||
GST_ERROR_OBJECT (self, "Couldn't execute command list");
|
GST_ERROR_OBJECT (self, "Couldn't execute command list");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstD3D12FenceData *fence_data;
|
if (priv->have_lut) {
|
||||||
gst_d3d12_device_acquire_fence_data (self->device, &fence_data);
|
D3D12_DESCRIPTOR_HEAP_DESC desc = { };
|
||||||
gst_d3d12_fence_data_push (fence_data, FENCE_NOTIFY_COM (cl.Detach ()));
|
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||||
gst_d3d12_fence_data_push (fence_data, FENCE_NOTIFY_COM (ca.Detach ()));
|
desc.NumDescriptors = 2;
|
||||||
gst_d3d12_fence_data_push (fence_data,
|
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||||
FENCE_NOTIFY_COM (upload_buf.Detach ()));
|
|
||||||
if (gamma_dec_lut_upload) {
|
auto hr = device->CreateDescriptorHeap (&desc,
|
||||||
gst_d3d12_fence_data_push (fence_data,
|
IID_PPV_ARGS (&priv->gamma_lut_heap));
|
||||||
FENCE_NOTIFY_COM (gamma_dec_lut_upload.Detach ()));
|
if (!gst_d3d12_result (hr, self->device)) {
|
||||||
|
GST_ERROR_OBJECT (self, "Couldn't create gamma lut heap");
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gamma_enc_lut_upload) {
|
auto cpu_handle =
|
||||||
gst_d3d12_fence_data_push (fence_data,
|
CD3DX12_CPU_DESCRIPTOR_HANDLE (GetCPUDescriptorHandleForHeapStart
|
||||||
FENCE_NOTIFY_COM (gamma_enc_lut_upload.Detach ()));
|
(priv->gamma_lut_heap));
|
||||||
}
|
|
||||||
|
|
||||||
gst_d3d12_cmd_queue_set_notify (priv->cq, priv->fence_val,
|
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = { };
|
||||||
FENCE_NOTIFY_MINI_OBJECT (fence_data));
|
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
|
||||||
|
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||||
|
srv_desc.Texture1D.MipLevels = 1;
|
||||||
|
|
||||||
|
device->CreateShaderResourceView (priv->gamma_dec_lut.Get (), &srv_desc,
|
||||||
|
cpu_handle);
|
||||||
|
cpu_handle.Offset (priv->srv_inc_size);
|
||||||
|
|
||||||
|
device->CreateShaderResourceView (priv->gamma_enc_lut.Get (), &srv_desc,
|
||||||
|
cpu_handle);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2410,7 +2236,7 @@ gst_d3d12_converter_execute (GstD3D12Converter * self, GstD3D12Frame * in_frame,
|
||||||
cl->SetGraphicsRootConstantBufferView (pipeline_data.crs->GetPsCbvIdx (),
|
cl->SetGraphicsRootConstantBufferView (pipeline_data.crs->GetPsCbvIdx (),
|
||||||
priv->const_buf_addr[pipeline_index]);
|
priv->const_buf_addr[pipeline_index]);
|
||||||
|
|
||||||
cl->IASetIndexBuffer (&priv->idv);
|
cl->IASetIndexBuffer (&priv->ibv);
|
||||||
cl->IASetVertexBuffers (0, 1, &priv->vbv);
|
cl->IASetVertexBuffers (0, 1, &priv->vbv);
|
||||||
cl->IASetPrimitiveTopology (D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
cl->IASetPrimitiveTopology (D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
cl->RSSetViewports (1, priv->viewport);
|
cl->RSSetViewports (1, priv->viewport);
|
||||||
|
@ -2534,6 +2360,20 @@ gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
|
||||||
gst_d3d12_frame_fence_gpu_wait (&out_frame, priv->cq);
|
gst_d3d12_frame_fence_gpu_wait (&out_frame, priv->cq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->setup_fence) {
|
||||||
|
auto default_queue = gst_d3d12_device_get_cmd_queue (converter->device,
|
||||||
|
D3D12_COMMAND_LIST_TYPE_DIRECT);
|
||||||
|
if (priv->cq != default_queue) {
|
||||||
|
auto completed = priv->setup_fence->GetCompletedValue ();
|
||||||
|
if (completed < priv->setup_fence_val) {
|
||||||
|
gst_d3d12_cmd_queue_execute_wait (priv->cq, priv->setup_fence.Get (),
|
||||||
|
priv->setup_fence_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->setup_fence = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
gst_d3d12_frame_unmap (&in_frame);
|
gst_d3d12_frame_unmap (&in_frame);
|
||||||
gst_d3d12_frame_unmap (&out_frame);
|
gst_d3d12_frame_unmap (&out_frame);
|
||||||
|
|
||||||
|
|
|
@ -100,5 +100,18 @@ HRESULT gst_d3d12_device_get_sampler_state (GstD3D12Device * device,
|
||||||
GST_D3D12_API
|
GST_D3D12_API
|
||||||
gboolean gst_d3d12_device_non_zeroed_supported (GstD3D12Device * device);
|
gboolean gst_d3d12_device_non_zeroed_supported (GstD3D12Device * device);
|
||||||
|
|
||||||
|
GST_D3D12_API
|
||||||
|
HRESULT gst_d3d12_device_get_converter_resources (GstD3D12Device * device,
|
||||||
|
ID3D12Resource * index_buf,
|
||||||
|
ID3D12Resource * index_upload,
|
||||||
|
const D3D12_VERTEX_BUFFER_VIEW * vbv,
|
||||||
|
const D3D12_INDEX_BUFFER_VIEW * ibv,
|
||||||
|
GstVideoTransferFunction gamma_dec_func,
|
||||||
|
ID3D12Resource ** gamma_dec,
|
||||||
|
GstVideoTransferFunction gamma_enc_func,
|
||||||
|
ID3D12Resource ** gamma_enc,
|
||||||
|
ID3D12Fence ** fence,
|
||||||
|
guint64 * fence_val);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "gstd3d12cmdlistpool.h"
|
#include "gstd3d12cmdlistpool.h"
|
||||||
#include <directx/d3dx12.h>
|
#include <directx/d3dx12.h>
|
||||||
#include <d3d11on12.h>
|
#include <d3d11on12.h>
|
||||||
|
#include <gst/d3dshader/gstd3dshader.h>
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -142,8 +143,13 @@ struct DeviceInner
|
||||||
gst_clear_object (©_cl_pool);
|
gst_clear_object (©_cl_pool);
|
||||||
|
|
||||||
gst_clear_object (&fence_data_pool);
|
gst_clear_object (&fence_data_pool);
|
||||||
|
gst_clear_object (&rtv_heap_pool);
|
||||||
|
|
||||||
|
gamma_dec_lut.clear();
|
||||||
|
gamma_enc_lut.clear();
|
||||||
samplers.clear ();
|
samplers.clear ();
|
||||||
|
gamma_lut_pso = nullptr;
|
||||||
|
gamma_lut_rs = nullptr;
|
||||||
|
|
||||||
factory = nullptr;
|
factory = nullptr;
|
||||||
adapter = nullptr;
|
adapter = nullptr;
|
||||||
|
@ -264,6 +270,12 @@ struct DeviceInner
|
||||||
|
|
||||||
GstD3D12FenceDataPool *fence_data_pool = nullptr;
|
GstD3D12FenceDataPool *fence_data_pool = nullptr;
|
||||||
|
|
||||||
|
ComPtr<ID3D12RootSignature> gamma_lut_rs;
|
||||||
|
ComPtr<ID3D12PipelineState> gamma_lut_pso;
|
||||||
|
std::unordered_map<DWORD, ComPtr<ID3D12Resource>> gamma_dec_lut;
|
||||||
|
std::unordered_map<DWORD, ComPtr<ID3D12Resource>> gamma_enc_lut;
|
||||||
|
GstD3D12DescHeapPool *rtv_heap_pool = nullptr;
|
||||||
|
|
||||||
guint rtv_inc_size;
|
guint rtv_inc_size;
|
||||||
|
|
||||||
guint adapter_index = 0;
|
guint adapter_index = 0;
|
||||||
|
@ -1392,6 +1404,17 @@ gst_d3d12_device_new_internal (const GstD3D12DeviceConstructData * data)
|
||||||
priv->non_zeroed_supported = TRUE;
|
priv->non_zeroed_supported = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC rtv_desc = { };
|
||||||
|
rtv_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||||
|
rtv_desc.NumDescriptors = 2;
|
||||||
|
rtv_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||||
|
|
||||||
|
priv->rtv_heap_pool = gst_d3d12_desc_heap_pool_new (device.Get (),
|
||||||
|
&rtv_desc);
|
||||||
|
GST_OBJECT_FLAG_SET (priv->rtv_heap_pool, GST_OBJECT_FLAG_MAY_BE_LEAKED);
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -2243,3 +2266,374 @@ gst_d3d12_flush_all_devices (void)
|
||||||
auto manager = DeviceCacheManager::GetInstance ();
|
auto manager = DeviceCacheManager::GetInstance ();
|
||||||
manager->FlushAll ();
|
manager->FlushAll ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline DWORD
|
||||||
|
gst_d3d12_transfer_func_to_gamma_func (GstVideoTransferFunction func)
|
||||||
|
{
|
||||||
|
enum class GammaFuncType
|
||||||
|
{
|
||||||
|
GAMMA10,
|
||||||
|
GAMMA18,
|
||||||
|
GAMMA20,
|
||||||
|
GAMMA22,
|
||||||
|
BT709,
|
||||||
|
SMPTE240M,
|
||||||
|
SRGB,
|
||||||
|
GAMMA28,
|
||||||
|
LOG100,
|
||||||
|
LOG316,
|
||||||
|
BT2020,
|
||||||
|
ADOBERGB,
|
||||||
|
PQ,
|
||||||
|
HLG,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (func) {
|
||||||
|
case GST_VIDEO_TRANSFER_GAMMA18:
|
||||||
|
return (DWORD) GammaFuncType::GAMMA18;
|
||||||
|
case GST_VIDEO_TRANSFER_GAMMA20:
|
||||||
|
return (DWORD) GammaFuncType::GAMMA20;
|
||||||
|
case GST_VIDEO_TRANSFER_GAMMA22:
|
||||||
|
return (DWORD) GammaFuncType::GAMMA22;
|
||||||
|
case GST_VIDEO_TRANSFER_BT601:
|
||||||
|
case GST_VIDEO_TRANSFER_BT709:
|
||||||
|
case GST_VIDEO_TRANSFER_BT2020_10:
|
||||||
|
return (DWORD) GammaFuncType::BT709;
|
||||||
|
case GST_VIDEO_TRANSFER_SMPTE240M:
|
||||||
|
return (DWORD) GammaFuncType::SMPTE240M;
|
||||||
|
case GST_VIDEO_TRANSFER_SRGB:
|
||||||
|
return (DWORD) GammaFuncType::SRGB;
|
||||||
|
case GST_VIDEO_TRANSFER_GAMMA28:
|
||||||
|
return (DWORD) GammaFuncType::GAMMA28;
|
||||||
|
case GST_VIDEO_TRANSFER_LOG100:
|
||||||
|
return (DWORD) GammaFuncType::LOG100;
|
||||||
|
case GST_VIDEO_TRANSFER_LOG316:
|
||||||
|
return (DWORD) GammaFuncType::LOG316;
|
||||||
|
case GST_VIDEO_TRANSFER_BT2020_12:
|
||||||
|
return (DWORD) GammaFuncType::BT2020;
|
||||||
|
case GST_VIDEO_TRANSFER_ADOBERGB:
|
||||||
|
return (DWORD) GammaFuncType::ADOBERGB;
|
||||||
|
case GST_VIDEO_TRANSFER_SMPTE2084:
|
||||||
|
return (DWORD) GammaFuncType::PQ;
|
||||||
|
case GST_VIDEO_TRANSFER_ARIB_STD_B67:
|
||||||
|
return (DWORD) GammaFuncType::HLG;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (DWORD) GammaFuncType::GAMMA10;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
gst_d3d12_device_get_converter_resources (GstD3D12Device * device,
|
||||||
|
ID3D12Resource * index_buf, ID3D12Resource * index_upload,
|
||||||
|
const D3D12_VERTEX_BUFFER_VIEW * vbv, const D3D12_INDEX_BUFFER_VIEW * ibv,
|
||||||
|
GstVideoTransferFunction gamma_dec_func, ID3D12Resource ** gamma_dec,
|
||||||
|
GstVideoTransferFunction gamma_enc_func, ID3D12Resource ** gamma_enc,
|
||||||
|
ID3D12Fence ** fence, guint64 * fence_val)
|
||||||
|
{
|
||||||
|
auto priv = device->priv->inner;
|
||||||
|
GstD3D12FenceData *fence_data = nullptr;
|
||||||
|
GstD3D12CmdAlloc *gst_ca = nullptr;
|
||||||
|
GstD3D12CmdList *gst_cl = nullptr;
|
||||||
|
bool need_lut = false;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
DWORD gamma_dec_func_d3d12 = 0;
|
||||||
|
DWORD gamma_enc_func_d3d12 = 0;
|
||||||
|
|
||||||
|
if (gamma_dec != nullptr && gamma_enc != nullptr)
|
||||||
|
need_lut = true;
|
||||||
|
|
||||||
|
if (need_lut) {
|
||||||
|
gamma_dec_func_d3d12 =
|
||||||
|
gst_d3d12_transfer_func_to_gamma_func (gamma_dec_func);
|
||||||
|
gamma_enc_func_d3d12 =
|
||||||
|
gst_d3d12_transfer_func_to_gamma_func (gamma_enc_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard < std::mutex > lk (priv->lock);
|
||||||
|
if (!priv->gamma_lut_rs) {
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAGS rs_flags =
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_AMPLIFICATION_SHADER_ROOT_ACCESS |
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_DENY_MESH_SHADER_ROOT_ACCESS;
|
||||||
|
D3D12_VERSIONED_ROOT_SIGNATURE_DESC rs_desc = { };
|
||||||
|
CD3DX12_ROOT_PARAMETER root_params[1];
|
||||||
|
|
||||||
|
root_params[0].InitAsConstants (2, 0);
|
||||||
|
|
||||||
|
CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC::Init_1_0 (rs_desc, 1, root_params,
|
||||||
|
0, nullptr, rs_flags);
|
||||||
|
|
||||||
|
ComPtr < ID3DBlob > rs_blob;
|
||||||
|
ComPtr < ID3DBlob > error_blob;
|
||||||
|
hr = D3DX12SerializeVersionedRootSignature (&rs_desc,
|
||||||
|
D3D_ROOT_SIGNATURE_VERSION_1, &rs_blob, &error_blob);
|
||||||
|
|
||||||
|
if (!gst_d3d12_result (hr, device)) {
|
||||||
|
const gchar *error_msg = nullptr;
|
||||||
|
if (error_blob)
|
||||||
|
error_msg = (const gchar *) error_blob->GetBufferPointer ();
|
||||||
|
|
||||||
|
GST_ERROR_OBJECT (device,
|
||||||
|
"Couldn't serialize root signature, hr: 0x%x, error detail: %s",
|
||||||
|
(guint) hr, GST_STR_NULL (error_msg));
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = priv->device->CreateRootSignature (0, rs_blob->GetBufferPointer (),
|
||||||
|
rs_blob->GetBufferSize (), IID_PPV_ARGS (&priv->gamma_lut_rs));
|
||||||
|
if (!gst_d3d12_result (hr, device)) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't create root signature");
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priv->gamma_lut_pso) {
|
||||||
|
GstD3DShaderByteCode vs_blob;
|
||||||
|
GstD3DShaderByteCode ps_blob;
|
||||||
|
if (!gst_d3d12_shader_cache_get_gamma_lut_blob (&vs_blob, &ps_blob)) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't get gamma decode byte code");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_INPUT_ELEMENT_DESC input_desc[2];
|
||||||
|
input_desc[0].SemanticName = "POSITION";
|
||||||
|
input_desc[0].SemanticIndex = 0;
|
||||||
|
input_desc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
||||||
|
input_desc[0].InputSlot = 0;
|
||||||
|
input_desc[0].AlignedByteOffset = D3D12_APPEND_ALIGNED_ELEMENT;
|
||||||
|
input_desc[0].InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
|
||||||
|
input_desc[0].InstanceDataStepRate = 0;
|
||||||
|
|
||||||
|
input_desc[1].SemanticName = "TEXCOORD";
|
||||||
|
input_desc[1].SemanticIndex = 0;
|
||||||
|
input_desc[1].Format = DXGI_FORMAT_R32G32_FLOAT;
|
||||||
|
input_desc[1].InputSlot = 0;
|
||||||
|
input_desc[1].AlignedByteOffset = D3D12_APPEND_ALIGNED_ELEMENT;
|
||||||
|
input_desc[1].InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
|
||||||
|
input_desc[1].InstanceDataStepRate = 0;
|
||||||
|
|
||||||
|
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = { };
|
||||||
|
pso_desc.pRootSignature = priv->gamma_lut_rs.Get ();
|
||||||
|
pso_desc.VS.pShaderBytecode = vs_blob.byte_code;
|
||||||
|
pso_desc.VS.BytecodeLength = vs_blob.byte_code_len;
|
||||||
|
pso_desc.PS.pShaderBytecode = ps_blob.byte_code;
|
||||||
|
pso_desc.PS.BytecodeLength = ps_blob.byte_code_len;
|
||||||
|
pso_desc.BlendState = CD3DX12_BLEND_DESC (D3D12_DEFAULT);
|
||||||
|
pso_desc.SampleMask = UINT_MAX;
|
||||||
|
pso_desc.RasterizerState = CD3DX12_RASTERIZER_DESC (D3D12_DEFAULT);
|
||||||
|
pso_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||||
|
pso_desc.DepthStencilState.DepthEnable = FALSE;
|
||||||
|
pso_desc.DepthStencilState.StencilEnable = FALSE;
|
||||||
|
pso_desc.InputLayout.pInputElementDescs = input_desc;
|
||||||
|
pso_desc.InputLayout.NumElements = 2;
|
||||||
|
pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||||
|
pso_desc.NumRenderTargets = 1;
|
||||||
|
pso_desc.RTVFormats[0] = DXGI_FORMAT_R16_UNORM;
|
||||||
|
pso_desc.SampleDesc.Count = 1;
|
||||||
|
pso_desc.SampleDesc.Quality = 0;
|
||||||
|
|
||||||
|
hr = priv->device->CreateGraphicsPipelineState (&pso_desc,
|
||||||
|
IID_PPV_ARGS (&priv->gamma_lut_pso));
|
||||||
|
if (!gst_d3d12_result (hr, device)) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't create gamma decode pso");
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_d3d12_fence_data_pool_acquire (priv->fence_data_pool, &fence_data);
|
||||||
|
|
||||||
|
gst_d3d12_cmd_alloc_pool_acquire (priv->direct_ca_pool, &gst_ca);
|
||||||
|
if (!gst_ca) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't acquire command allocator");
|
||||||
|
gst_d3d12_fence_data_unref (fence_data);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_d3d12_fence_data_push (fence_data, FENCE_NOTIFY_MINI_OBJECT (gst_ca));
|
||||||
|
|
||||||
|
auto ca = gst_d3d12_cmd_alloc_get_handle (gst_ca);
|
||||||
|
gst_d3d12_cmd_list_pool_acquire (priv->direct_cl_pool, ca, &gst_cl);
|
||||||
|
|
||||||
|
if (!gst_cl) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't acquire command list");
|
||||||
|
gst_d3d12_fence_data_unref (fence_data);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComPtr < ID3D12CommandList > cl_base;
|
||||||
|
ComPtr < ID3D12GraphicsCommandList > cl;
|
||||||
|
|
||||||
|
cl_base = gst_d3d12_cmd_list_get_handle (gst_cl);
|
||||||
|
cl_base.As (&cl);
|
||||||
|
|
||||||
|
cl->CopyResource (index_buf, index_upload);
|
||||||
|
index_buf->AddRef ();
|
||||||
|
gst_d3d12_fence_data_push (fence_data, FENCE_NOTIFY_COM (index_buf));
|
||||||
|
|
||||||
|
index_upload->AddRef ();
|
||||||
|
gst_d3d12_fence_data_push (fence_data, FENCE_NOTIFY_COM (index_upload));
|
||||||
|
|
||||||
|
D3D12_RESOURCE_BARRIER copy_barrier =
|
||||||
|
CD3DX12_RESOURCE_BARRIER::Transition (index_buf,
|
||||||
|
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
|
D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER |
|
||||||
|
D3D12_RESOURCE_STATE_INDEX_BUFFER,
|
||||||
|
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
|
||||||
|
|
||||||
|
cl->ResourceBarrier (1, ©_barrier);
|
||||||
|
|
||||||
|
bool store_dec = false;
|
||||||
|
bool store_enc = false;
|
||||||
|
ComPtr < ID3D12Resource > gamma_dec_resource;
|
||||||
|
ComPtr < ID3D12Resource > gamma_enc_resource;
|
||||||
|
|
||||||
|
if (need_lut) {
|
||||||
|
const UINT lut_size = 4096;
|
||||||
|
|
||||||
|
auto dec_iter = priv->gamma_dec_lut.find (gamma_dec_func_d3d12);
|
||||||
|
if (dec_iter != priv->gamma_dec_lut.end ()) {
|
||||||
|
GST_LOG_OBJECT (device, "Reuse gamma decode LUT");
|
||||||
|
gamma_dec_resource = dec_iter->second;
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (device, "Need to build gamma decode LUT");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto enc_iter = priv->gamma_enc_lut.find (gamma_enc_func_d3d12);
|
||||||
|
if (enc_iter != priv->gamma_enc_lut.end ()) {
|
||||||
|
GST_LOG_OBJECT (device, "Reuse gamma encode LUT");
|
||||||
|
gamma_enc_resource = enc_iter->second;
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (device, "Need to build gamma encode LUT");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gamma_dec_resource || !gamma_enc_resource) {
|
||||||
|
GstD3D12DescHeap *desc_heap = nullptr;
|
||||||
|
D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_NONE;
|
||||||
|
if (gst_d3d12_device_non_zeroed_supported (device))
|
||||||
|
heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
|
||||||
|
|
||||||
|
auto heap_prop = CD3DX12_HEAP_PROPERTIES (D3D12_HEAP_TYPE_DEFAULT);
|
||||||
|
auto resource_desc = CD3DX12_RESOURCE_DESC::Tex1D (DXGI_FORMAT_R16_UNORM,
|
||||||
|
lut_size, 1, 1, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET |
|
||||||
|
D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS);
|
||||||
|
|
||||||
|
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = { };
|
||||||
|
rtv_desc.Format = DXGI_FORMAT_R16_UNORM;
|
||||||
|
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE1D;
|
||||||
|
rtv_desc.Texture1D.MipSlice = 0;
|
||||||
|
|
||||||
|
gst_d3d12_desc_heap_pool_acquire (priv->rtv_heap_pool, &desc_heap);
|
||||||
|
if (!desc_heap) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't acquire descriptor heap");
|
||||||
|
gst_d3d12_fence_data_unref (fence_data);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_d3d12_fence_data_push (fence_data,
|
||||||
|
FENCE_NOTIFY_MINI_OBJECT (desc_heap));
|
||||||
|
|
||||||
|
auto desc_handle = gst_d3d12_desc_heap_get_handle (desc_heap);
|
||||||
|
auto cpu_handle = CD3DX12_CPU_DESCRIPTOR_HANDLE
|
||||||
|
(GetCPUDescriptorHandleForHeapStart (desc_handle));
|
||||||
|
|
||||||
|
cl->SetGraphicsRootSignature (priv->gamma_lut_rs.Get ());
|
||||||
|
cl->SetPipelineState (priv->gamma_lut_pso.Get ());
|
||||||
|
cl->IASetIndexBuffer (ibv);
|
||||||
|
cl->IASetVertexBuffers (0, 1, vbv);
|
||||||
|
cl->IASetPrimitiveTopology (D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
|
||||||
|
D3D12_VIEWPORT viewport = { };
|
||||||
|
viewport.Width = lut_size;
|
||||||
|
viewport.Height = 1;
|
||||||
|
viewport.MinDepth = 0;
|
||||||
|
viewport.MaxDepth = 1;
|
||||||
|
cl->RSSetViewports (1, &viewport);
|
||||||
|
|
||||||
|
D3D12_RECT scissor_rect = { };
|
||||||
|
scissor_rect.left = 0;
|
||||||
|
scissor_rect.top = 0;
|
||||||
|
scissor_rect.right = lut_size;
|
||||||
|
scissor_rect.bottom = 1;
|
||||||
|
cl->RSSetScissorRects (1, &scissor_rect);
|
||||||
|
|
||||||
|
if (!gamma_dec_resource) {
|
||||||
|
store_dec = true;
|
||||||
|
hr = priv->device->CreateCommittedResource (&heap_prop, heap_flags,
|
||||||
|
&resource_desc, D3D12_RESOURCE_STATE_COMMON, nullptr,
|
||||||
|
IID_PPV_ARGS (&gamma_dec_resource));
|
||||||
|
if (!gst_d3d12_result (hr, device)) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't create LUT texture");
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->device->CreateRenderTargetView (gamma_dec_resource.Get (),
|
||||||
|
&rtv_desc, cpu_handle);
|
||||||
|
|
||||||
|
cl->SetGraphicsRoot32BitConstant (0, 1, 0);
|
||||||
|
cl->SetGraphicsRoot32BitConstant (0, gamma_dec_func_d3d12, 1);
|
||||||
|
cl->OMSetRenderTargets (1, &cpu_handle, FALSE, nullptr);
|
||||||
|
cl->DrawIndexedInstanced (6, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
cpu_handle.Offset (priv->rtv_inc_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gamma_enc_resource) {
|
||||||
|
store_enc = true;
|
||||||
|
hr = priv->device->CreateCommittedResource (&heap_prop, heap_flags,
|
||||||
|
&resource_desc, D3D12_RESOURCE_STATE_COMMON, nullptr,
|
||||||
|
IID_PPV_ARGS (&gamma_enc_resource));
|
||||||
|
if (!gst_d3d12_result (hr, device)) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't create LUT texture");
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->device->CreateRenderTargetView (gamma_enc_resource.Get (),
|
||||||
|
&rtv_desc, cpu_handle);
|
||||||
|
|
||||||
|
cl->SetGraphicsRoot32BitConstant (0, 0, 0);
|
||||||
|
cl->SetGraphicsRoot32BitConstant (0, gamma_enc_func_d3d12, 1);
|
||||||
|
cl->OMSetRenderTargets (1, &cpu_handle, FALSE, nullptr);
|
||||||
|
cl->DrawIndexedInstanced (6, 1, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = cl->Close ();
|
||||||
|
if (!gst_d3d12_result (hr, device)) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't close command list");
|
||||||
|
gst_d3d12_fence_data_unref (fence_data);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12CommandList *cmd_list[] = { cl.Get () };
|
||||||
|
hr = gst_d3d12_cmd_queue_execute_command_lists (priv->direct_queue,
|
||||||
|
1, cmd_list, fence_val);
|
||||||
|
if (!gst_d3d12_result (hr, device)) {
|
||||||
|
GST_ERROR_OBJECT (device, "Couldn't execute command list");
|
||||||
|
gst_d3d12_fence_data_unref (fence_data);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_d3d12_cmd_queue_set_notify (priv->direct_queue, *fence_val, fence_data,
|
||||||
|
(GDestroyNotify) gst_d3d12_fence_data_unref);
|
||||||
|
|
||||||
|
if (need_lut) {
|
||||||
|
if (store_dec)
|
||||||
|
priv->gamma_dec_lut[gamma_dec_func_d3d12] = gamma_dec_resource;
|
||||||
|
if (store_enc)
|
||||||
|
priv->gamma_enc_lut[gamma_enc_func_d3d12] = gamma_enc_resource;
|
||||||
|
|
||||||
|
*gamma_dec = gamma_dec_resource.Detach ();
|
||||||
|
*gamma_enc = gamma_enc_resource.Detach ();
|
||||||
|
}
|
||||||
|
|
||||||
|
*fence = gst_d3d12_cmd_queue_get_fence_handle (priv->direct_queue);
|
||||||
|
(*fence)->AddRef ();
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue