1 /*
2 * Copyright (c) 2020-2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     encode_av1_brc_init_packet.cpp
24 //! \brief    Defines the interface for av1 brc init/reset packet
25 //!
26 #include "encode_av1_brc_init_packet.h"
27 #include "mhw_vdbox.h"
28 
29 namespace encode {
Init()30     MOS_STATUS Av1BrcInitPkt::Init()
31     {
32         ENCODE_FUNC_CALL();
33         ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::Init());
34         ENCODE_CHK_NULL_RETURN(m_featureManager);
35 
36         m_basicFeature = dynamic_cast<Av1BasicFeature *>(m_featureManager->GetFeature(Av1FeatureIDs::basicFeature));
37         ENCODE_CHK_NULL_RETURN(m_basicFeature);
38 
39         return MOS_STATUS_SUCCESS;
40     }
41 
AllocateResources()42     MOS_STATUS Av1BrcInitPkt::AllocateResources()
43     {
44         ENCODE_CHK_STATUS_RETURN(EncodeHucPkt::AllocateResources());
45 
46         // initiate allocation paramters
47         MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
48         MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
49         allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
50         allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
51         allocParamsForBufferLinear.Format = Format_Buffer;
52         allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
53         MOS_RESOURCE *allocatedbuffer;
54         for (auto k = 0; k < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; k++)
55         {
56             // BRC init/reset DMEM
57             allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcInitDmemBufferSize, CODECHAL_CACHELINE_SIZE);
58             allocParamsForBufferLinear.pBufName = "VDENC BrcInit DmemBuffer";
59             allocatedbuffer                     = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
60             ENCODE_CHK_NULL_RETURN(allocatedbuffer);
61             m_vdencBrcInitDmemBuffer[k] = *allocatedbuffer;
62         }
63 
64         return MOS_STATUS_SUCCESS;
65     }
66 
Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)67     MOS_STATUS Av1BrcInitPkt::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase)
68     {
69         ENCODE_FUNC_CALL();
70 
71         ENCODE_CHK_STATUS_RETURN(m_miItf->SetWatchdogTimerThreshold(m_basicFeature->m_frameWidth, m_basicFeature->m_frameHeight, true));
72 
73         bool firstTaskInPhase = packetPhase & firstPacket;
74         bool requestProlog = false;
75         auto brcFeature = dynamic_cast<Av1Brc*>(m_featureManager->GetFeature(Av1FeatureIDs::av1BrcFeature));
76         ENCODE_CHK_NULL_RETURN(brcFeature);
77 
78         uint16_t pictureType = (m_basicFeature->m_pictureCodingType == I_TYPE) ? 0 : (m_basicFeature->m_ref.IsLowDelay() ? (m_basicFeature->m_ref.IsPFrame() ? 1 : 3) : 2);
79         SetPerfTag(CODECHAL_ENCODE_PERFTAG_CALL_BRC_INIT_RESET, (uint16_t)m_basicFeature->m_mode, pictureType);
80 
81         if (!m_pipeline->IsSingleTaskPhaseSupported() || firstTaskInPhase)
82         {
83             // Send command buffer header at the beginning (OS dependent)
84             requestProlog = true;
85         }
86         ENCODE_CHK_STATUS_RETURN(Execute(commandBuffer, true, requestProlog, brcFeature->IsBRCResetRequired()? BRC_RESET : BRC_INIT));
87 
88         // Disable Brc Init/reset  here after init cmd executed, APP will re-trigger the reset by DDI params seqParams->resetBRC
89         RUN_FEATURE_INTERFACE_NO_RETURN(Av1Brc, Av1FeatureIDs::av1BrcFeature,
90             DisableBrcInitReset);
91 
92         return MOS_STATUS_SUCCESS;
93     }
94 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)95     MOS_STATUS Av1BrcInitPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
96     {
97         ENCODE_FUNC_CALL();
98 
99         auto osInterface = m_hwInterface->GetOsInterface();
100         ENCODE_CHK_NULL_RETURN(osInterface);
101 
102         uint32_t hucCommandsSize = 0;
103         uint32_t hucPatchListSize = 0;
104         MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
105 
106         ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucStateCommandSize(
107             m_basicFeature->m_mode, (uint32_t*)&hucCommandsSize, (uint32_t*)&hucPatchListSize, &stateCmdSizeParams));
108 
109         commandBufferSize = hucCommandsSize;
110         requestedPatchListSize = osInterface->bUsesPatchList ? hucPatchListSize : 0;
111 
112         // 4K align since allocation is in chunks of 4K bytes.
113         commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, CODECHAL_PAGE_SIZE);
114 
115         return MOS_STATUS_SUCCESS;
116     }
117 
118 #if USE_CODECHAL_DEBUG_TOOL
DumpInput()119     MOS_STATUS Av1BrcInitPkt::DumpInput()
120     {
121         ENCODE_FUNC_CALL();
122         int32_t currentPass = m_pipeline->GetCurrentPass();
123 
124         CodechalDebugInterface* debugInterface = m_pipeline->GetDebugInterface();
125         ENCODE_CHK_NULL_RETURN(debugInterface);
126 
127         ENCODE_CHK_STATUS_RETURN(debugInterface->DumpHucDmem(
128             &m_vdencBrcInitDmemBuffer[m_pipeline->m_currRecycledBufIdx],
129             m_vdencBrcInitDmemBufferSize,
130             currentPass,
131             hucRegionDumpInit));
132 
133         ENCODE_CHK_STATUS_RETURN(DumpRegion(0, "_BrcHistory", true, hucRegionDumpInit, 6080));
134         return MOS_STATUS_SUCCESS;
135     }
136 #endif
137 
MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE,Av1BrcInitPkt)138     MHW_SETPAR_DECL_SRC(HUC_IMEM_STATE, Av1BrcInitPkt)
139     {
140         params.kernelDescriptor = m_vdboxHucAv1BrcInitKernelDescriptor;
141 
142         return MOS_STATUS_SUCCESS;
143     }
144 
MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,Av1BrcInitPkt)145     MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, Av1BrcInitPkt)
146     {
147         params.function      = BRC_INIT;
148         params.hucDataSource = const_cast<PMOS_RESOURCE>(&m_vdencBrcInitDmemBuffer[m_pipeline->m_currRecycledBufIdx]);
149         params.dataLength    = MOS_ALIGN_CEIL(m_vdencBrcInitDmemBufferSize, CODECHAL_CACHELINE_SIZE);
150         params.dmemOffset    = HUC_DMEM_OFFSET_RTOS_GEMS;
151         return MOS_STATUS_SUCCESS;
152     }
153 
MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE,Av1BrcInitPkt)154     MHW_SETPAR_DECL_SRC(HUC_VIRTUAL_ADDR_STATE, Av1BrcInitPkt)
155     {
156         ENCODE_CHK_NULL_RETURN(m_basicFeature);
157         ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf);
158 
159         params.regionParams[0].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencBRCHistoryBuffer, 0);
160         params.regionParams[0].isWritable = true;
161 
162         return MOS_STATUS_SUCCESS;
163     }
164 
MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH,Av1BrcInitPkt)165     MHW_SETPAR_DECL_SRC(VD_PIPELINE_FLUSH, Av1BrcInitPkt)
166     {
167         params.waitDoneVDCmdMsgParser = true;
168         params.waitDoneAV1 = true;
169         params.flushAV1 = true;
170 
171         return MOS_STATUS_SUCCESS;
172     }
173 }
174