mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 13:10:10 +01:00
d3d12: Use lower size estimations for compressed output bitstream sizes
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37565>
This commit is contained in:
parent
0395dca6d6
commit
b2b009fc29
3 changed files with 66 additions and 4 deletions
|
|
@ -2402,6 +2402,55 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc
|
|||
return true;
|
||||
}
|
||||
|
||||
// Helper function to calculate the max output bitstream size based on width, height, and format
|
||||
// This function uses an approach based on common video formats and their typical compression ratios
|
||||
inline
|
||||
UINT d3d12_video_encoder_calculate_max_output_compressed_bitstream_size(
|
||||
UINT uiWidth,
|
||||
UINT uiHeight,
|
||||
DXGI_FORMAT format
|
||||
)
|
||||
{
|
||||
assert((uiHeight > 16) &&
|
||||
(uiWidth > 16) &&
|
||||
(format != DXGI_FORMAT_UNKNOWN));
|
||||
|
||||
const UINT MIN_BUFFER_SIZE = 128 * 128 * 2; // Minimum buffer size for very small frames: 128x128 pixels at 2 bytes/pixel
|
||||
const UINT MAX_BUFFER_SIZE = 20 * 1024 * 1024; // Maximum buffer size of 20MB
|
||||
const float EXPECTED_COMPRESSION_FACTOR = 2.0f; // Assume 50% of calculated size after compression of raw pixel sizes
|
||||
|
||||
UINT alignedWidth = (uiWidth + 15) & ~15;
|
||||
UINT alignedHeight = (uiHeight + 15) & ~15;
|
||||
UINT bufferSize = 0;
|
||||
switch (format) {
|
||||
case DXGI_FORMAT_NV12:
|
||||
// NV12: Y plane (1 byte/pixel) + UV plane (1/2 byte/pixel) = 1.5 bytes/pixel
|
||||
bufferSize = alignedWidth * alignedHeight * 3 / 2;
|
||||
break;
|
||||
case DXGI_FORMAT_P010:
|
||||
// P010: Y plane (2 bytes/pixel) + UV plane (1 byte/pixel) = 3 bytes/pixel
|
||||
bufferSize = alignedWidth * alignedHeight * 3;
|
||||
break;
|
||||
case DXGI_FORMAT_AYUV:
|
||||
// AYUV: 4 bytes/pixel
|
||||
bufferSize = alignedWidth * alignedHeight * 4;
|
||||
break;
|
||||
default:
|
||||
// Fallback formula for other formats: assume 15 bits/pixel (1.875 bytes/pixel)
|
||||
bufferSize = (((alignedHeight) * (alignedWidth) * 15) >> 3);
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply EXPECTED_COMPRESSION_FACTOR constant (% of calculated size)
|
||||
bufferSize = static_cast<UINT>(std::ceil(bufferSize / EXPECTED_COMPRESSION_FACTOR));
|
||||
|
||||
// Clamp buffer size between minimum and maximum limits
|
||||
bufferSize = std::max(MIN_BUFFER_SIZE, std::min(bufferSize, MAX_BUFFER_SIZE));
|
||||
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
|
||||
struct pipe_video_codec *
|
||||
d3d12_video_encoder_create_encoder(struct pipe_context *context, const struct pipe_video_codec *codec)
|
||||
{
|
||||
|
|
@ -2445,6 +2494,20 @@ d3d12_video_encoder_create_encoder(struct pipe_context *context, const struct pi
|
|||
goto failed;
|
||||
}
|
||||
|
||||
pD3D12Enc->m_MaxOutputBitstreamSize = d3d12_video_encoder_calculate_max_output_compressed_bitstream_size(
|
||||
codec->width,
|
||||
codec->height,
|
||||
d3d12_convert_pipe_video_profile_to_dxgi_format(pD3D12Enc->base.profile)
|
||||
);
|
||||
|
||||
debug_printf("[d3d12_video_encoder] d3d12_video_encoder_create_encoder - Calculated max output bitstream size: %u bytes (%u Kb, %u Mb) for %ux%u DXGI_FORMAT %u\n",
|
||||
pD3D12Enc->m_MaxOutputBitstreamSize,
|
||||
pD3D12Enc->m_MaxOutputBitstreamSize / 1024,
|
||||
pD3D12Enc->m_MaxOutputBitstreamSize / (1024 * 1024),
|
||||
codec->width,
|
||||
codec->height,
|
||||
static_cast<UINT>(d3d12_convert_pipe_video_profile_to_dxgi_format(pD3D12Enc->base.profile)));
|
||||
|
||||
if (!d3d12_video_encoder_create_command_objects(pD3D12Enc)) {
|
||||
debug_printf("[d3d12_video_encoder] d3d12_video_encoder_create_encoder - Failure on "
|
||||
"d3d12_video_encoder_create_command_objects\n");
|
||||
|
|
@ -3225,7 +3288,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
|||
pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].spStagingBitstreams[0/*first slice*/];
|
||||
} else if (pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].spStagingBitstreams[slice_idx] == nullptr) {
|
||||
D3D12_HEAP_PROPERTIES Properties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
|
||||
CD3DX12_RESOURCE_DESC resolvedMetadataBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(D3D12_DEFAULT_COMPBIT_STAGING_SIZE);
|
||||
CD3DX12_RESOURCE_DESC resolvedMetadataBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(pD3D12Enc->m_MaxOutputBitstreamSize);
|
||||
HRESULT hr = pD3D12Enc->m_pD3D12Screen->dev->CreateCommittedResource(
|
||||
&Properties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
|
|
@ -4356,7 +4419,7 @@ d3d12_video_encoder_get_feedback(struct pipe_video_codec *codec,
|
|||
templ.target = PIPE_BUFFER;
|
||||
templ.usage = PIPE_USAGE_DEFAULT;
|
||||
templ.format = PIPE_FORMAT_R8_UINT;
|
||||
templ.width0 = D3D12_DEFAULT_COMPBIT_STAGING_SIZE;
|
||||
templ.width0 = pD3D12Enc->m_MaxOutputBitstreamSize;
|
||||
templ.height0 = 1;
|
||||
templ.depth0 = 1;
|
||||
templ.array_size = 1;
|
||||
|
|
|
|||
|
|
@ -574,6 +574,7 @@ struct d3d12_video_encoder
|
|||
|
||||
const uint m_NodeMask = 0u;
|
||||
const uint m_NodeIndex = 0u;
|
||||
UINT m_MaxOutputBitstreamSize = 0;
|
||||
|
||||
ComPtr<ID3D12Fence> m_spFence;
|
||||
uint64_t m_fenceValue = 1u;
|
||||
|
|
|
|||
|
|
@ -75,8 +75,6 @@ const size_t D3D12_VIDEO_ENC_METADATA_BUFFERS_COUNT = static_cast<size_t>(debug_
|
|||
|
||||
constexpr unsigned int D3D12_VIDEO_H264_MB_IN_PIXELS = 16;
|
||||
|
||||
constexpr size_t D3D12_DEFAULT_COMPBIT_STAGING_SIZE = (1024 /*1K*/ * 1024/*1MB*/) * 8/*8 MB*/; // 8MB
|
||||
|
||||
/* If enabled, the D3D12 AV1 encoder will use always ...CONFIGURABLE_GRID_PARTITION mode */
|
||||
/* If disabled, the D3D12 AV1 encoder will try to use ...UNIFORM_GRID_PARTITION first and then fallback to ...CONFIGURABLE_GRID_PARTITION if not possible */
|
||||
const bool D3D12_VIDEO_FORCE_TILE_MODE = debug_get_bool_option("D3D12_VIDEO_FORCE_TILE_MODE", false);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue