1 /*
2 * Copyright (c) 2019, 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     decode_predication_packet.cpp
24 //! \brief    Defines the interface for decode predication sub packet
25 //!
26 #include "decode_predication_packet.h"
27 #include "decode_common_feature_defs.h"
28 
29 namespace decode
30 {
31 
DecodePredicationPkt(DecodePipeline * pipeline,CodechalHwInterfaceNext * hwInterface)32 DecodePredicationPkt::DecodePredicationPkt(DecodePipeline *pipeline, CodechalHwInterfaceNext *hwInterface)
33     : DecodeSubPacket(pipeline, hwInterface)
34 {
35     m_hwInterface = hwInterface;
36 }
37 
Init()38 MOS_STATUS DecodePredicationPkt::Init()
39 {
40     DECODE_CHK_NULL(m_pipeline);
41     DECODE_CHK_NULL(m_hwInterface);
42 
43     m_miItf = m_hwInterface->GetMiInterfaceNext();
44     DECODE_CHK_NULL(m_miItf);
45 
46     MediaFeatureManager *featureManager = m_pipeline->GetFeatureManager();
47     DECODE_CHK_NULL(featureManager);
48 
49     m_predication = dynamic_cast<DecodePredication*>(
50                     featureManager->GetFeature(DecodeFeatureIDs::decodePredication));
51     DECODE_CHK_NULL(m_predication);
52 
53     return MOS_STATUS_SUCCESS;
54 }
55 
Prepare()56 MOS_STATUS DecodePredicationPkt::Prepare()
57 {
58     return MOS_STATUS_SUCCESS;
59 }
60 
Execute(MOS_COMMAND_BUFFER & cmdBuffer)61 MOS_STATUS DecodePredicationPkt::Execute(MOS_COMMAND_BUFFER& cmdBuffer)
62 {
63     if (!m_predication->m_predicationEnabled)
64     {
65         return MOS_STATUS_SUCCESS;
66     }
67 
68     MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS  condBBEndParams;
69     MOS_ZeroMemory(&condBBEndParams, sizeof(condBBEndParams));
70 
71     // Skip current frame if presPredication is not equal to zero
72     if (m_predication->m_predicationNotEqualZero)
73     {
74         auto mmioRegistersMfx = m_hwInterface->SelectVdAndGetMmioReg(MHW_VDBOX_NODE_1, &cmdBuffer);
75         auto &flushDwParams    = m_miItf->MHW_GETPAR_F(MI_FLUSH_DW)();
76         flushDwParams          = {};
77         ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FLUSH_DW)(&cmdBuffer));
78 
79         // load presPredication to general purpose register0
80         auto &miLoadRegMemParams           = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_MEM)();
81         miLoadRegMemParams                 = {};
82         miLoadRegMemParams.presStoreBuffer = &m_predication->m_resPredication->OsResource;
83         miLoadRegMemParams.dwOffset        = (uint32_t)m_predication->m_predicationResOffset;
84         miLoadRegMemParams.dwRegister      = mmioRegistersMfx->generalPurposeRegister0LoOffset;
85         DECODE_CHK_STATUS(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_MEM)(&cmdBuffer));
86 
87         auto &miLoadRegImmParams      = m_miItf->MHW_GETPAR_F(MI_LOAD_REGISTER_IMM)();
88         miLoadRegImmParams            = {};
89         miLoadRegImmParams.dwData     = 0;
90         miLoadRegImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister0HiOffset;
91         DECODE_CHK_STATUS(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(&cmdBuffer));
92 
93         // load 0 to general purpose register4
94         miLoadRegImmParams            = {};
95         miLoadRegImmParams.dwData     = 0;
96         miLoadRegImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister4LoOffset;
97         DECODE_CHK_STATUS(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(&cmdBuffer));
98 
99         miLoadRegImmParams            = {};
100         miLoadRegImmParams.dwData     = 0;
101         miLoadRegImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister4HiOffset;
102         DECODE_CHK_STATUS(m_miItf->MHW_ADDCMD_F(MI_LOAD_REGISTER_IMM)(&cmdBuffer));
103 
104         //perform the add operation
105         mhw::mi::MHW_MI_ALU_PARAMS miAluParams[4] = {};
106         // load     srcA, reg0
107         miAluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
108         miAluParams[0].Operand1 = MHW_MI_ALU_SRCA;
109         miAluParams[0].Operand2 = MHW_MI_ALU_GPREG0;
110         // load     srcB, reg4
111         miAluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
112         miAluParams[1].Operand1 = MHW_MI_ALU_SRCB;
113         miAluParams[1].Operand2 = MHW_MI_ALU_GPREG4;
114         // add      srcA, srcB
115         miAluParams[2].AluOpcode = MHW_MI_ALU_ADD;
116         miAluParams[2].Operand1 = MHW_MI_ALU_SRCB;
117         miAluParams[2].Operand2 = MHW_MI_ALU_GPREG4;
118         // store      reg0, ZF
119         miAluParams[3].AluOpcode = MHW_MI_ALU_STORE;
120         miAluParams[3].Operand1 = MHW_MI_ALU_GPREG0;
121         miAluParams[3].Operand2 = MHW_MI_ALU_ZF;
122 
123         auto &miMathParams = m_miItf->MHW_GETPAR_F(MI_MATH)();
124         miMathParams       = {};
125         miMathParams.pAluPayload = miAluParams;
126         miMathParams.dwNumAluParams = 4;  // four ALU commands needed for this substract opertaion. see following ALU commands.
127         DECODE_CHK_STATUS(m_miItf->MHW_ADDCMD_F(MI_MATH)(&cmdBuffer));
128 
129 
130         // if zero, the zero flag will be 0xFFFFFFFF, else zero flag will be 0x0.
131         auto &miStoreRegMemParams           = m_miItf->MHW_GETPAR_F(MI_STORE_REGISTER_MEM)();
132         miStoreRegMemParams                 = {};
133         miStoreRegMemParams.presStoreBuffer = &m_predication->m_predicationBuffer->OsResource;
134         miStoreRegMemParams.dwOffset        = 0;
135         miStoreRegMemParams.dwRegister      = mmioRegistersMfx->generalPurposeRegister0LoOffset;
136         DECODE_CHK_STATUS(m_miItf->MHW_ADDCMD_F(MI_STORE_REGISTER_MEM)(&cmdBuffer));
137 
138         auto &miConditionalBatchBufferEndParams               = m_miItf->MHW_GETPAR_F(MI_CONDITIONAL_BATCH_BUFFER_END)();
139         miConditionalBatchBufferEndParams                     = {};
140         miConditionalBatchBufferEndParams.dwOffset            = 0;
141         miConditionalBatchBufferEndParams.dwValue             = 0;
142         miConditionalBatchBufferEndParams.bDisableCompareMask = true;
143         miConditionalBatchBufferEndParams.presSemaphoreBuffer = &m_predication->m_predicationBuffer->OsResource;
144         DECODE_CHK_STATUS(m_miItf->MHW_ADDCMD_F(MI_CONDITIONAL_BATCH_BUFFER_END)(&cmdBuffer));
145     }
146     else
147     {
148         // Skip current frame if presPredication is equal to zero
149         auto &miConditionalBatchBufferEndParams               = m_miItf->MHW_GETPAR_F(MI_CONDITIONAL_BATCH_BUFFER_END)();
150         miConditionalBatchBufferEndParams                     = {};
151         miConditionalBatchBufferEndParams.dwOffset            = (uint32_t)m_predication->m_predicationResOffset;
152         miConditionalBatchBufferEndParams.dwValue             = 0;
153         miConditionalBatchBufferEndParams.bDisableCompareMask = true;
154         miConditionalBatchBufferEndParams.presSemaphoreBuffer = &m_predication->m_resPredication->OsResource;
155         DECODE_CHK_STATUS(m_miItf->MHW_ADDCMD_F(MI_CONDITIONAL_BATCH_BUFFER_END)(&cmdBuffer));
156     }
157 
158     return MOS_STATUS_SUCCESS;
159 }
160 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)161 MOS_STATUS DecodePredicationPkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
162 {
163     commandBufferSize = 0;
164     requestedPatchListSize = 0;
165     return MOS_STATUS_SUCCESS;
166 }
167 
168 }
169