81 SDL_IOStream *rw = SDL_IOFromConstMem(data,
static_cast<int>(size));
83 FLINT_ENGINE_ERROR(
"Failed to create IO stream from memory");
87 SDL_Surface *loaded = IMG_Load_IO(rw,
true);
89 FLINT_ENGINE_ERROR(
"Failed to load image: {}", SDL_GetError());
93 SDL_Surface *surface = loaded;
94 if (loaded->format != SDL_PIXELFORMAT_RGBA32) {
95 surface = SDL_ConvertSurface(loaded, SDL_PIXELFORMAT_RGBA32);
96 SDL_DestroySurface(loaded);
98 FLINT_ENGINE_ERROR(
"Failed to convert surface to RGBA32: {}", SDL_GetError());
103 m_width = surface->w;
104 m_height = surface->h;
106 const Uint32 bytesPerRow =
static_cast<Uint32
>(m_width) * 4;
107 const Uint32 dataSize = bytesPerRow *
static_cast<Uint32
>(m_height);
109 SDL_GPUTextureCreateInfo textureInfo = {};
110 textureInfo.type = SDL_GPU_TEXTURETYPE_2D;
111 textureInfo.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
112 textureInfo.width = m_width;
113 textureInfo.height = m_height;
114 textureInfo.layer_count_or_depth = 1;
115 textureInfo.num_levels = 1;
116 textureInfo.sample_count = SDL_GPU_SAMPLECOUNT_1;
117 textureInfo.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER;
119 m_texture = SDL_CreateGPUTexture(m_device, &textureInfo);
121 FLINT_ENGINE_ERROR(
"Failed to create GPU texture: {}", SDL_GetError());
122 SDL_DestroySurface(surface);
126 SDL_GPUCommandBuffer *uploadCmd = SDL_AcquireGPUCommandBuffer(m_device);
128 FLINT_ENGINE_ERROR(
"Failed to acquire command buffer for upload");
129 SDL_DestroySurface(surface);
130 GPU_RELEASE_TEXTURE(m_device, m_texture);
134 SDL_GPUCopyPass *copyPass = SDL_BeginGPUCopyPass(uploadCmd);
136 FLINT_ENGINE_ERROR(
"Failed to begin GPU copy pass: {}", SDL_GetError());
140 SDL_GPUTransferBufferCreateInfo transferBufferInfo = {};
141 transferBufferInfo.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
142 transferBufferInfo.size = dataSize;
144 SDL_GPUTransferBuffer *transferBuffer = SDL_CreateGPUTransferBuffer(m_device,
145 &transferBufferInfo);
146 if (!transferBuffer) {
147 FLINT_ENGINE_ERROR(
"Failed to create transfer buffer");
148 SDL_DestroySurface(surface);
149 SDL_EndGPUCopyPass(copyPass);
150 SDL_SubmitGPUCommandBuffer(uploadCmd);
154 void *mapped = SDL_MapGPUTransferBuffer(m_device, transferBuffer,
false);
156 FLINT_ENGINE_ERROR(
"Failed to map transfer buffer: {}", SDL_GetError());
157 SDL_EndGPUCopyPass(copyPass);
158 SDL_SubmitGPUCommandBuffer(uploadCmd);
159 SDL_ReleaseGPUTransferBuffer(m_device, transferBuffer);
160 GPU_RELEASE_TEXTURE(m_device, m_texture);
161 SDL_DestroySurface(surface);
164 auto *dstBytes =
static_cast<Uint8 *
>(mapped);
165 auto *srcBytes =
static_cast<const Uint8 *
>(surface->pixels);
166 for (
int y = 0; y < m_height; ++y) {
167 memcpy(dstBytes + y * bytesPerRow, srcBytes + y * surface->pitch, bytesPerRow);
169 SDL_UnmapGPUTransferBuffer(m_device, transferBuffer);
171 SDL_GPUTextureTransferInfo uploadInfo = {};
172 uploadInfo.transfer_buffer = transferBuffer;
173 uploadInfo.offset = 0;
174 uploadInfo.pixels_per_row = m_width;
175 uploadInfo.rows_per_layer = m_height;
177 SDL_GPUTextureRegion textureRegion = {};
178 textureRegion.texture = m_texture;
179 textureRegion.w = m_width;
180 textureRegion.h = m_height;
183 SDL_UploadToGPUTexture(copyPass, &uploadInfo, &textureRegion,
false);
185 SDL_EndGPUCopyPass(copyPass);
186 SDL_SubmitGPUCommandBuffer(uploadCmd);
188 SDL_ReleaseGPUTransferBuffer(m_device, transferBuffer);
189 SDL_DestroySurface(surface);
191 SDL_GPUSamplerCreateInfo samplerInfo = {};
192 samplerInfo.min_filter = SDL_GPU_FILTER_NEAREST;
193 samplerInfo.mag_filter = SDL_GPU_FILTER_NEAREST;
194 samplerInfo.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_NEAREST;
195 samplerInfo.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
196 samplerInfo.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
197 samplerInfo.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
199 m_sampler = SDL_CreateGPUSampler(m_device, &samplerInfo);
201 FLINT_ENGINE_ERROR(
"Failed to create GPU sampler: {}", SDL_GetError());
202 GPU_RELEASE_TEXTURE(m_device, m_texture);
206 FLINT_ENGINE_INFO(
"GPU texture loaded successfully ({}x{})", m_width, m_height);