1/*
2 * Copyright (C) 2018-2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 */
7
8#include "opencl/source/kernel/kernel.h"
9#include "opencl/source/program/block_kernel_manager.h"
10#include "opencl/source/program/printf_handler.h"
11
12namespace NEO {
13
14template <bool mockable>
15void Kernel::patchReflectionSurface(DeviceQueue *devQueue, PrintfHandler *printfHandler) {
16
17    void *reflectionSurface = kernelReflectionSurface->getUnderlyingBuffer();
18
19    BlockKernelManager *blockManager = program->getBlockKernelManager();
20    uint32_t blockCount = static_cast<uint32_t>(blockManager->getCount());
21
22    for (uint32_t i = 0; i < blockCount; i++) {
23        const KernelInfo *pBlockInfo = blockManager->getBlockKernelInfo(i);
24
25        uint64_t printfBufferOffset = ReflectionSurfaceHelper::undefinedOffset;
26        uint32_t printfBufferPatchSize = 0U;
27        const auto &printfSurface = pBlockInfo->kernelDescriptor.payloadMappings.implicitArgs.printfSurfaceAddress;
28        if (isValidOffset(printfSurface.stateless)) {
29            printfBufferOffset = printfSurface.stateless;
30            printfBufferPatchSize = printfSurface.pointerSize;
31        }
32        uint64_t printfGpuAddress = 0;
33
34        uint64_t eventPoolOffset = ReflectionSurfaceHelper::undefinedOffset;
35        uint32_t eventPoolSize = 0U;
36        const auto &eventPoolSurfaceAddress = pBlockInfo->kernelDescriptor.payloadMappings.implicitArgs.deviceSideEnqueueEventPoolSurfaceAddress;
37        if (isValidOffset(eventPoolSurfaceAddress.stateless)) {
38            eventPoolOffset = eventPoolSurfaceAddress.stateless;
39            eventPoolSize = eventPoolSurfaceAddress.pointerSize;
40        }
41
42        uint64_t defaultQueueOffset = ReflectionSurfaceHelper::undefinedOffset;
43        uint32_t defaultQueueSize = 0U;
44        const auto &defaultQueueSurface = pBlockInfo->kernelDescriptor.payloadMappings.implicitArgs.deviceSideEnqueueDefaultQueueSurfaceAddress;
45        if (isValidOffset(defaultQueueSurface.stateless)) {
46            defaultQueueOffset = defaultQueueSurface.stateless;
47            defaultQueueSize = defaultQueueSurface.pointerSize;
48        }
49
50        uint64_t deviceQueueOffset = ReflectionSurfaceHelper::undefinedOffset;
51        uint32_t deviceQueueSize = 0;
52
53        uint64_t privateSurfaceOffset = ReflectionSurfaceHelper::undefinedOffset;
54        uint32_t privateSurfacePatchSize = 0;
55        uint64_t privateSurfaceGpuAddress = 0;
56
57        auto privateSurface = blockManager->getPrivateSurface(i);
58
59        UNRECOVERABLE_IF((pBlockInfo->kernelDescriptor.kernelAttributes.perHwThreadPrivateMemorySize > 0U) && privateSurface == nullptr);
60        if (privateSurface) {
61            const auto &privateMemory = pBlockInfo->kernelDescriptor.payloadMappings.implicitArgs.privateMemoryAddress;
62            UNRECOVERABLE_IF(false == isValidOffset(privateMemory.stateless));
63            privateSurfaceOffset = privateMemory.stateless;
64            privateSurfacePatchSize = privateMemory.pointerSize;
65            privateSurfaceGpuAddress = privateSurface->getGpuAddressToPatch();
66        }
67
68        if (printfHandler) {
69            GraphicsAllocation *printfSurface = printfHandler->getSurface();
70
71            if (printfSurface)
72                printfGpuAddress = printfSurface->getGpuAddress();
73        }
74
75        for (const auto &arg : pBlockInfo->kernelDescriptor.payloadMappings.explicitArgs) {
76            if (arg.getExtendedTypeInfo().isDeviceQueue) {
77                const auto &argAsPtr = arg.as<ArgDescPointer>();
78                deviceQueueOffset = argAsPtr.stateless;
79                deviceQueueSize = argAsPtr.pointerSize;
80                break;
81            }
82        }
83
84        ReflectionSurfaceHelper::patchBlocksCurbe<mockable>(reflectionSurface, i,
85                                                            defaultQueueOffset, defaultQueueSize, devQueue->getQueueBuffer()->getGpuAddress(),
86                                                            eventPoolOffset, eventPoolSize, devQueue->getEventPoolBuffer()->getGpuAddress(),
87                                                            deviceQueueOffset, deviceQueueSize, devQueue->getQueueBuffer()->getGpuAddress(),
88                                                            printfBufferOffset, printfBufferPatchSize, printfGpuAddress,
89                                                            privateSurfaceOffset, privateSurfacePatchSize, privateSurfaceGpuAddress);
90    }
91
92    ReflectionSurfaceHelper::setParentImageParams(reflectionSurface, this->kernelArguments, kernelInfo);
93    ReflectionSurfaceHelper::setParentSamplerParams(reflectionSurface, this->kernelArguments, kernelInfo);
94}
95} // namespace NEO
96