| 1 | #include <nn/gfx/detail/gfx_Buffer-api.nvn.8.h> |
| 2 | |
| 3 | #include <nn/gfx/detail/gfx_Device-api.nvn.8.h> |
| 4 | #include <nn/gfx/detail/gfx_MemoryPool-api.nvn.8.h> |
| 5 | #include <nn/gfx/gfx_BufferInfo.h> |
| 6 | |
| 7 | #include <algorithm> |
| 8 | |
| 9 | #include "gfx_NvnHelper.h" |
| 10 | |
| 11 | namespace nn::gfx::detail { |
| 12 | |
| 13 | namespace { |
| 14 | |
| 15 | void SetupTextureBuilder(NVNtextureBuilder* pBuilder, NVNdevice* pDevice, |
| 16 | const BufferTextureViewInfo& info) { |
| 17 | const BufferImpl<ApiVariationNvn8>* pBuffer = info.GetBufferPtr(); |
| 18 | NVNbuffer* pNvnBuffer = pBuffer->ToData()->pNvnBuffer; |
| 19 | NVNformat nvnFormat = Nvn::GetImageFormat(info.GetImageFormat()); |
| 20 | |
| 21 | NVNmemoryPool* pNvnMemoryPool; |
| 22 | ptrdiff_t bufferOffset = 0; |
| 23 | |
| 24 | pNvnMemoryPool = nvnBufferGetMemoryPool(buffer: pNvnBuffer); |
| 25 | bufferOffset = nvnBufferGetMemoryOffset(buffer: pNvnBuffer); |
| 26 | |
| 27 | nvnTextureBuilderSetDevice(builder: pBuilder, device: pDevice); |
| 28 | nvnTextureBuilderSetDefaults(builder: pBuilder); |
| 29 | nvnTextureBuilderSetWidth(builder: pBuilder, width: info.GetSize()); |
| 30 | nvnTextureBuilderSetHeight(builder: pBuilder, height: 1); |
| 31 | nvnTextureBuilderSetDepth(builder: pBuilder, depth: 1); |
| 32 | nvnTextureBuilderSetFormat(builder: pBuilder, format: nvnFormat); |
| 33 | nvnTextureBuilderSetTarget(builder: pBuilder, target: NVN_TEXTURE_TARGET_BUFFER); |
| 34 | nvnTextureBuilderSetFlags(builder: pBuilder, flags: NVN_TEXTURE_FLAGS_IMAGE); |
| 35 | nvnTextureBuilderSetStorage(builder: pBuilder, pool: pNvnMemoryPool, offset: info.GetOffset() + bufferOffset); |
| 36 | } |
| 37 | } // namespace |
| 38 | |
| 39 | size_t BufferImpl<ApiVariationNvn8>::GetBufferAlignment(DeviceImpl<ApiVariationNvn8>* pDevice, |
| 40 | const BufferInfo& info) { |
| 41 | int gpuAccessFlag = info.GetGpuAccessFlags(); |
| 42 | int alignment = 8; |
| 43 | |
| 44 | if (gpuAccessFlag & GpuAccess_ConstantBuffer) { |
| 45 | int uniformBufferAlignment; |
| 46 | nvnDeviceGetInteger(device: pDevice->ToData()->pNvnDevice, pname: NVN_DEVICE_INFO_UNIFORM_BUFFER_ALIGNMENT, |
| 47 | v: &uniformBufferAlignment); |
| 48 | alignment = std::max(a: alignment, b: uniformBufferAlignment); |
| 49 | } |
| 50 | |
| 51 | if (gpuAccessFlag & GpuAccess_IndirectBuffer) { |
| 52 | int indirectBufferAlignment; |
| 53 | nvnDeviceGetInteger(device: pDevice->ToData()->pNvnDevice, pname: NVN_DEVICE_INFO_INDIRECT_DRAW_ALIGNMENT, |
| 54 | v: &indirectBufferAlignment); |
| 55 | alignment = std::max(a: alignment, b: indirectBufferAlignment); |
| 56 | |
| 57 | nvnDeviceGetInteger(device: pDevice->ToData()->pNvnDevice, |
| 58 | pname: NVN_DEVICE_INFO_INDIRECT_DISPATCH_ALIGNMENT, v: &indirectBufferAlignment); |
| 59 | alignment = std::max(a: alignment, b: indirectBufferAlignment); |
| 60 | } |
| 61 | |
| 62 | if (gpuAccessFlag & GpuAccess_QueryBuffer) { |
| 63 | int counterAlignment; |
| 64 | nvnDeviceGetInteger(device: pDevice->ToData()->pNvnDevice, pname: NVN_DEVICE_INFO_COUNTER_ALIGNMENT, |
| 65 | v: &counterAlignment); |
| 66 | alignment = std::max(a: alignment, b: counterAlignment); |
| 67 | } |
| 68 | |
| 69 | if (gpuAccessFlag & GpuAccess_UnorderedAccessBuffer) { |
| 70 | alignment = std::max(a: alignment, b: 32); |
| 71 | } |
| 72 | |
| 73 | if (gpuAccessFlag & (GpuAccess_DepthStencil | GpuAccess_ColorBuffer | GpuAccess_Texture)) { |
| 74 | alignment = std::max(a: alignment, b: 512); |
| 75 | } |
| 76 | |
| 77 | return alignment; |
| 78 | } |
| 79 | |
| 80 | BufferImpl<ApiVariationNvn8>::BufferImpl() { |
| 81 | state = State_NotInitialized; |
| 82 | } |
| 83 | |
| 84 | BufferImpl<ApiVariationNvn8>::~BufferImpl() {} |
| 85 | |
| 86 | void BufferImpl<ApiVariationNvn8>::Initialize(DeviceImpl<ApiVariationNvn8>* pDevice, |
| 87 | const BufferInfo& info, |
| 88 | MemoryPoolImpl<ApiVariationNvn8>* pMemoryPool, |
| 89 | ptrdiff_t memoryPoolOffset, |
| 90 | [[maybe_unused]] size_t memoryPoolSize) { |
| 91 | NVNbufferBuilder builder; |
| 92 | |
| 93 | nvnBufferBuilderSetDefaults(builder: &builder); |
| 94 | nvnBufferBuilderSetDevice(builder: &builder, device: pDevice->ToData()->pNvnDevice); |
| 95 | nvnBufferBuilderSetStorage(builder: &builder, pool: pMemoryPool->ToData()->pNvnMemoryPool, offset: memoryPoolOffset, |
| 96 | size: info.GetSize()); |
| 97 | |
| 98 | pNvnBuffer = &nvnBuffer; |
| 99 | |
| 100 | nvnBufferInitialize(buffer: pNvnBuffer, builder: &builder); |
| 101 | |
| 102 | int nvnMemoryPoolFlags = nvnMemoryPoolGetFlags(pool: pMemoryPool->ToData()->pNvnMemoryPool); |
| 103 | |
| 104 | flags.SetBit(p: Flag_CpuCached, on: nvnMemoryPoolFlags & NVN_MEMORY_POOL_FLAGS_CPU_CACHED); |
| 105 | flags.SetBit(p: Flag_Shared, on: false); |
| 106 | state = State_Initialized; |
| 107 | } |
| 108 | |
| 109 | void BufferImpl<ApiVariationNvn8>::Finalize(DeviceImpl<ApiVariationNvn8>*) { |
| 110 | nvnBufferFinalize(buffer: pNvnBuffer); |
| 111 | pNvnBuffer = nullptr; |
| 112 | state = State_NotInitialized; |
| 113 | } |
| 114 | |
| 115 | void* BufferImpl<ApiVariationNvn8>::Map() const { |
| 116 | return nvnBufferMap(buffer: pNvnBuffer); |
| 117 | } |
| 118 | |
| 119 | void BufferImpl<ApiVariationNvn8>::Unmap() const {} |
| 120 | |
| 121 | void BufferImpl<ApiVariationNvn8>::FlushMappedRange(ptrdiff_t offset, size_t flushSize) const { |
| 122 | if (flags.GetBit(p: Flag_CpuCached)) { |
| 123 | nvnBufferFlushMappedRange(buffer: pNvnBuffer, offset, size: flushSize); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | void BufferImpl<ApiVariationNvn8>::InvalidateMappedRange(ptrdiff_t offset, |
| 128 | size_t invalidateSize) const { |
| 129 | if (flags.GetBit(p: Flag_CpuCached)) { |
| 130 | nvnBufferInvalidateMappedRange(buffer: pNvnBuffer, offset, size: invalidateSize); |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | void BufferImpl<ApiVariationNvn8>::GetGpuAddress(GpuAddress* pOutGpuAddress) const { |
| 135 | pOutGpuAddress->ToData()->value = nvnBufferGetAddress(buffer: pNvnBuffer); |
| 136 | pOutGpuAddress->ToData()->impl = 0; |
| 137 | } |
| 138 | |
| 139 | size_t |
| 140 | BufferTextureViewImpl<ApiVariationNvn8>::GetOffsetAlignment(DeviceImpl<ApiVariationNvn8>* pDevice, |
| 141 | const BufferTextureViewInfo& info) { |
| 142 | NVNtextureBuilder builder; |
| 143 | SetupTextureBuilder(pBuilder: &builder, pDevice: pDevice->ToData()->pNvnDevice, info); |
| 144 | |
| 145 | size_t alignment = 0; |
| 146 | alignment = nvnTextureBuilderGetStorageAlignment(builder: &builder); |
| 147 | return alignment; |
| 148 | } |
| 149 | |
| 150 | BufferTextureViewImpl<ApiVariationNvn8>::BufferTextureViewImpl() { |
| 151 | state = State_NotInitialized; |
| 152 | } |
| 153 | |
| 154 | BufferTextureViewImpl<ApiVariationNvn8>::~BufferTextureViewImpl() {} |
| 155 | |
| 156 | void BufferTextureViewImpl<ApiVariationNvn8>::Initialize(DeviceImpl<ApiVariationNvn8>* pDevice, |
| 157 | const BufferTextureViewInfo& info) { |
| 158 | pNvnTexture = &nvnTexture; |
| 159 | |
| 160 | NVNtextureBuilder builder; |
| 161 | SetupTextureBuilder(pBuilder: &builder, pDevice: pDevice->ToData()->pNvnDevice, info); |
| 162 | |
| 163 | nvnTextureInitialize(texture: pNvnTexture, builder: &builder); |
| 164 | |
| 165 | flags.SetBit(p: Flag_Shared, on: false); |
| 166 | state = State_Initialized; |
| 167 | } |
| 168 | |
| 169 | void BufferTextureViewImpl<ApiVariationNvn8>::Finalize(DeviceImpl<ApiVariationNvn8>*) { |
| 170 | nvnTextureFinalize(texture: pNvnTexture); |
| 171 | pNvnTexture = nullptr; |
| 172 | state = State_NotInitialized; |
| 173 | } |
| 174 | |
| 175 | } // namespace nn::gfx::detail |