1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2023 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief CTS implementation of the NVIDIA BitstreamBuffer interface. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci /* 24e5c31af7Sopenharmony_ci * Copyright 2023 NVIDIA Corporation. 25e5c31af7Sopenharmony_ci * 26e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 27e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 28e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 29e5c31af7Sopenharmony_ci * 30e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 31e5c31af7Sopenharmony_ci * 32e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 33e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 34e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 36e5c31af7Sopenharmony_ci * limitations under the License. 37e5c31af7Sopenharmony_ci */ 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ci#include "vktBitstreamBufferImpl.hpp" 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci#include <cstring> 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_cinamespace vkt 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_cinamespace video 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ciVkResult 49e5c31af7Sopenharmony_ciBitstreamBufferImpl::Create(DeviceContext* devctx, deUint32 queueFamilyIndex, VkDeviceSize bufferSize, VkDeviceSize bufferOffsetAlignment, VkDeviceSize bufferSizeAlignment, VkSharedBaseObj<BitstreamBufferImpl>& vulkanBitstreamBuffer, const VkVideoProfileListInfoKHR* profileList) 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci VkSharedBaseObj<BitstreamBufferImpl> vkBitstreamBuffer(new BitstreamBufferImpl(devctx, 52e5c31af7Sopenharmony_ci queueFamilyIndex, 53e5c31af7Sopenharmony_ci bufferOffsetAlignment, 54e5c31af7Sopenharmony_ci bufferSizeAlignment, 55e5c31af7Sopenharmony_ci profileList)); 56e5c31af7Sopenharmony_ci DE_ASSERT(vkBitstreamBuffer); 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ci VK_CHECK(vkBitstreamBuffer->Initialize(bufferSize)); 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ci vulkanBitstreamBuffer = vkBitstreamBuffer; 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_ci return VK_SUCCESS; 63e5c31af7Sopenharmony_ci} 64e5c31af7Sopenharmony_ci 65e5c31af7Sopenharmony_ciVkResult BitstreamBufferImpl::Initialize(VkDeviceSize bufferSize) 66e5c31af7Sopenharmony_ci{ 67e5c31af7Sopenharmony_ci auto& vk = m_devctx->getDeviceDriver(); 68e5c31af7Sopenharmony_ci auto device = m_devctx->device; 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci if (m_bufferSize >= bufferSize) 71e5c31af7Sopenharmony_ci { 72e5c31af7Sopenharmony_ci VkDeviceSize size = MemsetData(0x00, 0, m_bufferSize); 73e5c31af7Sopenharmony_ci DE_ASSERT(size == m_bufferSize); 74e5c31af7Sopenharmony_ci DE_UNREF(size); 75e5c31af7Sopenharmony_ci return VK_SUCCESS; 76e5c31af7Sopenharmony_ci } 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci VkBufferCreateInfo createBufferInfo = {}; 79e5c31af7Sopenharmony_ci createBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 80e5c31af7Sopenharmony_ci createBufferInfo.pNext = m_profileList; 81e5c31af7Sopenharmony_ci createBufferInfo.size = deAlignSize(bufferSize, m_bufferSizeAlignment); 82e5c31af7Sopenharmony_ci createBufferInfo.usage = VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR; 83e5c31af7Sopenharmony_ci createBufferInfo.flags = 0; 84e5c31af7Sopenharmony_ci createBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 85e5c31af7Sopenharmony_ci createBufferInfo.queueFamilyIndexCount = 1; 86e5c31af7Sopenharmony_ci createBufferInfo.pQueueFamilyIndices = &m_queueFamilyIndex; 87e5c31af7Sopenharmony_ci m_bitstreamBuffer = BufferPtr(new BufferWithMemory(vk, device, m_devctx->allocator(), createBufferInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::Cached)); 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci m_bufferSize = bufferSize; 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci return VK_SUCCESS; 92e5c31af7Sopenharmony_ci} 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ciVkResult BitstreamBufferImpl::CopyDataToBuffer(const deUint8* pData, 95e5c31af7Sopenharmony_ci VkDeviceSize size, 96e5c31af7Sopenharmony_ci VkDeviceSize& dstBufferOffset) const 97e5c31af7Sopenharmony_ci{ 98e5c31af7Sopenharmony_ci DE_ASSERT((pData != nullptr) && (size > 0) && (size < 10 * 1024 * 1024)); // 10 MiB should be big enough for any CTS test. 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci dstBufferOffset = deAlignSize(dstBufferOffset, m_bufferOffsetAlignment); 101e5c31af7Sopenharmony_ci DE_ASSERT((dstBufferOffset + size) <= m_bufferSize); 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ci auto* bitstreamBasePtr = static_cast<deUint8*>(m_bitstreamBuffer->getAllocation().getHostPtr()); 104e5c31af7Sopenharmony_ci deMemcpy(bitstreamBasePtr + dstBufferOffset, pData, size); 105e5c31af7Sopenharmony_ci vk::flushAlloc(m_devctx->getDeviceDriver(), m_devctx->device, m_bitstreamBuffer->getAllocation()); 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci return VK_SUCCESS; 108e5c31af7Sopenharmony_ci} 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ciVkDeviceSize BitstreamBufferImpl::GetMaxSize() const 111e5c31af7Sopenharmony_ci{ 112e5c31af7Sopenharmony_ci return m_bufferSize; 113e5c31af7Sopenharmony_ci} 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ciVkDeviceSize BitstreamBufferImpl::GetOffsetAlignment() const 116e5c31af7Sopenharmony_ci{ 117e5c31af7Sopenharmony_ci return m_bufferOffsetAlignment; 118e5c31af7Sopenharmony_ci} 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ciVkDeviceSize BitstreamBufferImpl::GetSizeAlignment() const 121e5c31af7Sopenharmony_ci{ 122e5c31af7Sopenharmony_ci // REVIEW: Cache this? 123e5c31af7Sopenharmony_ci auto reqs = getBufferMemoryRequirements(m_devctx->getDeviceDriver(), m_devctx->device, m_bitstreamBuffer->get()); 124e5c31af7Sopenharmony_ci return reqs.alignment; 125e5c31af7Sopenharmony_ci} 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ciVkDeviceSize BitstreamBufferImpl::Resize(VkDeviceSize, VkDeviceSize, VkDeviceSize) 128e5c31af7Sopenharmony_ci{ 129e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Bitstream buffers should never need to be resized in the CTS"); 130e5c31af7Sopenharmony_ci} 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ciVkDeviceSize BitstreamBufferImpl::Clone(VkDeviceSize, VkDeviceSize, VkDeviceSize, 133e5c31af7Sopenharmony_ci VkSharedBaseObj<VulkanBitstreamBuffer>&) 134e5c31af7Sopenharmony_ci{ 135e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Presentation only interface from the samples app should not be needed in CTS"); 136e5c31af7Sopenharmony_ci} 137e5c31af7Sopenharmony_ci 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_cideUint8* BitstreamBufferImpl::CheckAccess(VkDeviceSize offset, VkDeviceSize size) const 140e5c31af7Sopenharmony_ci{ 141e5c31af7Sopenharmony_ci DE_ASSERT(size > 0 && offset + size < m_bufferSize); 142e5c31af7Sopenharmony_ci DE_UNREF(size); 143e5c31af7Sopenharmony_ci auto* bitstreamBasePtr = static_cast<deUint8*>(m_bitstreamBuffer->getAllocation().getHostPtr()); 144e5c31af7Sopenharmony_ci return static_cast<deUint8*>(bitstreamBasePtr + offset); 145e5c31af7Sopenharmony_ci} 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_ciint64_t BitstreamBufferImpl::MemsetData(deUint32 value, VkDeviceSize offset, VkDeviceSize size) 148e5c31af7Sopenharmony_ci{ 149e5c31af7Sopenharmony_ci if (size == 0) 150e5c31af7Sopenharmony_ci { 151e5c31af7Sopenharmony_ci return 0; 152e5c31af7Sopenharmony_ci } 153e5c31af7Sopenharmony_ci auto* bitstreamBasePtr = static_cast<deUint8*>(m_bitstreamBuffer->getAllocation().getHostPtr()); 154e5c31af7Sopenharmony_ci deMemset(bitstreamBasePtr + offset, value, size); 155e5c31af7Sopenharmony_ci vk::flushAlloc(m_devctx->getDeviceDriver(), m_devctx->device, m_bitstreamBuffer->getAllocation()); 156e5c31af7Sopenharmony_ci return size; 157e5c31af7Sopenharmony_ci} 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_ciint64_t BitstreamBufferImpl::CopyDataToBuffer(deUint8* dstBuffer, VkDeviceSize dstOffset, VkDeviceSize srcOffset, VkDeviceSize size) const 160e5c31af7Sopenharmony_ci{ 161e5c31af7Sopenharmony_ci if (size == 0) 162e5c31af7Sopenharmony_ci { 163e5c31af7Sopenharmony_ci return 0; 164e5c31af7Sopenharmony_ci } 165e5c31af7Sopenharmony_ci auto* bitstreamBasePtr = static_cast<deUint8*>(m_bitstreamBuffer->getAllocation().getHostPtr()); 166e5c31af7Sopenharmony_ci deMemcpy(dstBuffer + dstOffset, bitstreamBasePtr + srcOffset, size); 167e5c31af7Sopenharmony_ci return size; 168e5c31af7Sopenharmony_ci} 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ciint64_t BitstreamBufferImpl::CopyDataToBuffer(VkSharedBaseObj<VulkanBitstreamBuffer>& dstBuffer, VkDeviceSize dstOffset, VkDeviceSize srcOffset, VkDeviceSize size) const 171e5c31af7Sopenharmony_ci{ 172e5c31af7Sopenharmony_ci if (size == 0) 173e5c31af7Sopenharmony_ci { 174e5c31af7Sopenharmony_ci return 0; 175e5c31af7Sopenharmony_ci } 176e5c31af7Sopenharmony_ci const deUint8* readData = CheckAccess(srcOffset, size); 177e5c31af7Sopenharmony_ci DE_ASSERT(readData); 178e5c31af7Sopenharmony_ci return dstBuffer->CopyDataFromBuffer(readData, 0, dstOffset, size); 179e5c31af7Sopenharmony_ci} 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ciint64_t BitstreamBufferImpl::CopyDataFromBuffer(const deUint8* sourceBuffer, VkDeviceSize srcOffset, VkDeviceSize dstOffset, VkDeviceSize size) 182e5c31af7Sopenharmony_ci{ 183e5c31af7Sopenharmony_ci if (size == 0) 184e5c31af7Sopenharmony_ci { 185e5c31af7Sopenharmony_ci return 0; 186e5c31af7Sopenharmony_ci } 187e5c31af7Sopenharmony_ci auto* bitstreamBasePtr = static_cast<deUint8*>(m_bitstreamBuffer->getAllocation().getHostPtr()); 188e5c31af7Sopenharmony_ci deMemcpy(bitstreamBasePtr + dstOffset, sourceBuffer + srcOffset, size); 189e5c31af7Sopenharmony_ci return size; 190e5c31af7Sopenharmony_ci} 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ciint64_t BitstreamBufferImpl::CopyDataFromBuffer(const VkSharedBaseObj<VulkanBitstreamBuffer>& sourceBuffer, 193e5c31af7Sopenharmony_ci VkDeviceSize srcOffset, 194e5c31af7Sopenharmony_ci VkDeviceSize dstOffset, 195e5c31af7Sopenharmony_ci VkDeviceSize size) 196e5c31af7Sopenharmony_ci{ 197e5c31af7Sopenharmony_ci if (size == 0) 198e5c31af7Sopenharmony_ci { 199e5c31af7Sopenharmony_ci return 0; 200e5c31af7Sopenharmony_ci } 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_ci const deUint8* readData = sourceBuffer->GetReadOnlyDataPtr(srcOffset, size); 203e5c31af7Sopenharmony_ci DE_ASSERT(readData); 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci auto* bitstreamBasePtr = static_cast<deUint8*>(m_bitstreamBuffer->getAllocation().getHostPtr()); 206e5c31af7Sopenharmony_ci deMemcpy(bitstreamBasePtr + dstOffset, readData + srcOffset, size); 207e5c31af7Sopenharmony_ci return size; 208e5c31af7Sopenharmony_ci} 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_cideUint8* BitstreamBufferImpl::GetDataPtr(VkDeviceSize offset, VkDeviceSize& maxSize) 211e5c31af7Sopenharmony_ci{ 212e5c31af7Sopenharmony_ci deUint8* readData = CheckAccess(offset, 1); 213e5c31af7Sopenharmony_ci DE_ASSERT(readData); 214e5c31af7Sopenharmony_ci maxSize = m_bufferSize - offset; 215e5c31af7Sopenharmony_ci return readData; 216e5c31af7Sopenharmony_ci} 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ciconst deUint8* BitstreamBufferImpl::GetReadOnlyDataPtr(VkDeviceSize offset, VkDeviceSize& maxSize) const 219e5c31af7Sopenharmony_ci{ 220e5c31af7Sopenharmony_ci deUint8* readData = CheckAccess(offset, 1); 221e5c31af7Sopenharmony_ci DE_ASSERT(readData); 222e5c31af7Sopenharmony_ci maxSize = m_bufferSize - offset; 223e5c31af7Sopenharmony_ci return readData; 224e5c31af7Sopenharmony_ci} 225e5c31af7Sopenharmony_ci 226e5c31af7Sopenharmony_civoid BitstreamBufferImpl::FlushRange(VkDeviceSize /*offset*/, VkDeviceSize size) const 227e5c31af7Sopenharmony_ci{ 228e5c31af7Sopenharmony_ci if (size == 0) 229e5c31af7Sopenharmony_ci { 230e5c31af7Sopenharmony_ci return; 231e5c31af7Sopenharmony_ci } 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci // TOOD: Plumb the size and offset alignment caps into this class to invalidate just the range asked for in the API, rather than the whole range. 234e5c31af7Sopenharmony_ci vk::flushAlloc(m_devctx->getDeviceDriver(), m_devctx->device, m_bitstreamBuffer->getAllocation()); 235e5c31af7Sopenharmony_ci} 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_civoid BitstreamBufferImpl::InvalidateRange(VkDeviceSize /*offset*/, VkDeviceSize size) const 238e5c31af7Sopenharmony_ci{ 239e5c31af7Sopenharmony_ci if (size == 0) 240e5c31af7Sopenharmony_ci { 241e5c31af7Sopenharmony_ci return; 242e5c31af7Sopenharmony_ci } 243e5c31af7Sopenharmony_ci // TOOD: Plumb the size and offset alignment caps into this class to invalidate just the range asked for in the API, rather than the whole range. 244e5c31af7Sopenharmony_ci vk::flushAlloc(m_devctx->getDeviceDriver(), m_devctx->device, m_bitstreamBuffer->getAllocation()); 245e5c31af7Sopenharmony_ci} 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_cideUint32 BitstreamBufferImpl::AddStreamMarker(deUint32 streamOffset) 248e5c31af7Sopenharmony_ci{ 249e5c31af7Sopenharmony_ci m_streamMarkers.push_back(streamOffset); 250e5c31af7Sopenharmony_ci return (deUint32)(m_streamMarkers.size() - 1); 251e5c31af7Sopenharmony_ci} 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_cideUint32 BitstreamBufferImpl::SetStreamMarker(deUint32 streamOffset, deUint32 index) 254e5c31af7Sopenharmony_ci{ 255e5c31af7Sopenharmony_ci DE_ASSERT(index < (deUint32)m_streamMarkers.size()); 256e5c31af7Sopenharmony_ci if (!(index < (deUint32)m_streamMarkers.size())) 257e5c31af7Sopenharmony_ci { 258e5c31af7Sopenharmony_ci return deUint32(-1); 259e5c31af7Sopenharmony_ci } 260e5c31af7Sopenharmony_ci m_streamMarkers[index] = streamOffset; 261e5c31af7Sopenharmony_ci return index; 262e5c31af7Sopenharmony_ci} 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_cideUint32 BitstreamBufferImpl::GetStreamMarker(deUint32 index) const 265e5c31af7Sopenharmony_ci{ 266e5c31af7Sopenharmony_ci DE_ASSERT(index < (deUint32)m_streamMarkers.size()); 267e5c31af7Sopenharmony_ci return m_streamMarkers[index]; 268e5c31af7Sopenharmony_ci} 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_cideUint32 BitstreamBufferImpl::GetStreamMarkersCount() const 271e5c31af7Sopenharmony_ci{ 272e5c31af7Sopenharmony_ci return (deUint32)m_streamMarkers.size(); 273e5c31af7Sopenharmony_ci} 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_ciconst deUint32* BitstreamBufferImpl::GetStreamMarkersPtr(deUint32 startIndex, deUint32& maxCount) const 276e5c31af7Sopenharmony_ci{ 277e5c31af7Sopenharmony_ci maxCount = (deUint32)m_streamMarkers.size() - startIndex; 278e5c31af7Sopenharmony_ci return m_streamMarkers.data() + startIndex; 279e5c31af7Sopenharmony_ci} 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_cideUint32 BitstreamBufferImpl::ResetStreamMarkers() 282e5c31af7Sopenharmony_ci{ 283e5c31af7Sopenharmony_ci deUint32 oldSize = (deUint32)m_streamMarkers.size(); 284e5c31af7Sopenharmony_ci m_streamMarkers.clear(); 285e5c31af7Sopenharmony_ci return oldSize; 286e5c31af7Sopenharmony_ci} 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci} // namespace video 289e5c31af7Sopenharmony_ci} // namespace vkt 290