[Phi] adding full formats support, finishing blitter port from software
Mirror Gitea refs to GitHub / mirror (push) Successful in 13s
Test / build_and_test (push) Successful in 5m42s
Build / build (push) Successful in 7m19s

blitter
This commit is contained in:
2026-08-21 22:38:31 +02:00
parent cbbe113b9b
commit 2525dded67
10 changed files with 2206 additions and 236 deletions
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
#ifndef APE_PHI_BLIT_FORMATS_H
#define APE_PHI_BLIT_FORMATS_H
#include <Protocol.h>
#include <stdint.h>
typedef struct PhiBlitFormatInfo
{
uint32_t texel_size;
uint8_t is_integer;
uint8_t is_signed;
uint8_t is_float;
uint8_t is_srgb;
uint8_t is_unsigned;
uint8_t can_read_float;
uint8_t can_write_float;
uint8_t can_read_int;
uint8_t can_write_int;
uint8_t vector_unorm8x4;
} PhiBlitFormatInfo;
typedef struct PhiBlitFloat4
{
float values[4];
} PhiBlitFloat4;
typedef struct PhiBlitInt4
{
uint32_t values[4];
} PhiBlitInt4;
int PhiGetBlitFormatInfo(PhiFormat format, PhiBlitFormatInfo* info);
PhiBlitFloat4 PhiReadBlitFloat4(const uint8_t* map, PhiFormat format);
void PhiWriteBlitFloat4(PhiBlitFloat4 color, uint8_t* map, PhiFormat format);
PhiBlitInt4 PhiReadBlitInt4(const uint8_t* map, PhiFormat format);
void PhiWriteBlitInt4(PhiBlitInt4 color, uint8_t* map, PhiFormat format);
PhiBlitFloat4 PhiConvertBlitFloat4(PhiBlitFloat4 color,
PhiFormat src_format,
PhiFormat dst_format,
int allow_srgb_conversion,
int apply_srgb_conversion);
#endif
+146 -189
View File
@@ -1,3 +1,4 @@
#include <BlitFormats.h>
#include <Blitter.h>
#include <Logger.h>
#include <Memory.h>
@@ -8,7 +9,6 @@
#include <stddef.h>
#include <stdint.h>
#define UNORM8_SCALE (1.0f / 255.0f)
#define BLIT_WEIGHT_SCALE 1024.0f
#define BLIT_PARALLEL_MIN_PIXELS (256u * 1024u)
#define BLIT_TASK_TARGET_BYTES (64u * 1024u)
@@ -20,18 +20,8 @@ enum
PHI_FILTER_LINEAR = 1,
};
typedef struct Color
{
float r;
float g;
float b;
float a;
} Color;
typedef struct FormatInfo
{
uint32_t texel_size;
} FormatInfo;
typedef PhiBlitFloat4 Color;
typedef PhiBlitFormatInfo FormatInfo;
typedef struct SampleCoordinate
{
@@ -51,149 +41,11 @@ typedef struct BlitWork
uint64_t rows_per_layer;
} BlitWork;
static int GetFormatInfo(PhiFormat format, FormatInfo* info)
{
switch(format)
{
case PHI_FORMAT_R8_UNORM:
info->texel_size = 1;
return 1;
case PHI_FORMAT_R8G8_UNORM:
info->texel_size = 2;
return 1;
case PHI_FORMAT_R8G8B8_UNORM:
case PHI_FORMAT_B8G8R8_UNORM:
info->texel_size = 3;
return 1;
case PHI_FORMAT_R8G8B8A8_UNORM:
case PHI_FORMAT_B8G8R8A8_UNORM:
case PHI_FORMAT_A8B8G8R8_UNORM_PACK32:
info->texel_size = 4;
return 1;
default:
return 0;
}
}
static Color ReadUnorm8(const uint8_t* texel, PhiFormat format)
{
Color color = { 0.0f, 0.0f, 0.0f, 1.0f };
switch(format)
{
case PHI_FORMAT_R8_UNORM:
color.r = (float)texel[0] * UNORM8_SCALE;
break;
case PHI_FORMAT_R8G8_UNORM:
color.r = (float)texel[0] * UNORM8_SCALE;
color.g = (float)texel[1] * UNORM8_SCALE;
break;
case PHI_FORMAT_R8G8B8_UNORM:
color.r = (float)texel[0] * UNORM8_SCALE;
color.g = (float)texel[1] * UNORM8_SCALE;
color.b = (float)texel[2] * UNORM8_SCALE;
break;
case PHI_FORMAT_B8G8R8_UNORM:
color.r = (float)texel[2] * UNORM8_SCALE;
color.g = (float)texel[1] * UNORM8_SCALE;
color.b = (float)texel[0] * UNORM8_SCALE;
break;
case PHI_FORMAT_R8G8B8A8_UNORM:
case PHI_FORMAT_A8B8G8R8_UNORM_PACK32:
color.r = (float)texel[0] * UNORM8_SCALE;
color.g = (float)texel[1] * UNORM8_SCALE;
color.b = (float)texel[2] * UNORM8_SCALE;
color.a = (float)texel[3] * UNORM8_SCALE;
break;
case PHI_FORMAT_B8G8R8A8_UNORM:
color.r = (float)texel[2] * UNORM8_SCALE;
color.g = (float)texel[1] * UNORM8_SCALE;
color.b = (float)texel[0] * UNORM8_SCALE;
color.a = (float)texel[3] * UNORM8_SCALE;
break;
default:
break;
}
return color;
}
static inline uint8_t QuantizeUnorm8(float value)
{
if(value <= 0.0f)
return 0;
if(value >= 1.0f)
return UINT8_MAX;
return (uint8_t)(value * 255.0f + 0.5f);
}
static void WriteUnorm8(uint8_t* texel, PhiFormat format, Color color)
{
const uint8_t r = QuantizeUnorm8(color.r);
const uint8_t g = QuantizeUnorm8(color.g);
const uint8_t b = QuantizeUnorm8(color.b);
const uint8_t a = QuantizeUnorm8(color.a);
switch(format)
{
case PHI_FORMAT_R8_UNORM:
texel[0] = r;
break;
case PHI_FORMAT_R8G8_UNORM:
texel[0] = r;
texel[1] = g;
break;
case PHI_FORMAT_R8G8B8_UNORM:
texel[0] = r;
texel[1] = g;
texel[2] = b;
break;
case PHI_FORMAT_B8G8R8_UNORM:
texel[0] = b;
texel[1] = g;
texel[2] = r;
break;
case PHI_FORMAT_R8G8B8A8_UNORM:
case PHI_FORMAT_A8B8G8R8_UNORM_PACK32:
texel[0] = r;
texel[1] = g;
texel[2] = b;
texel[3] = a;
break;
case PHI_FORMAT_B8G8R8A8_UNORM:
texel[0] = b;
texel[1] = g;
texel[2] = r;
texel[3] = a;
break;
default:
break;
}
}
static inline Color LerpColor(Color a, Color b, float factor)
{
Color result;
result.r = a.r + (b.r - a.r) * factor;
result.g = a.g + (b.g - a.g) * factor;
result.b = a.b + (b.b - a.b) * factor;
result.a = a.a + (b.a - a.a) * factor;
for(uint32_t component = 0; component < 4; ++component)
result.values[component] = a.values[component] + (b.values[component] - a.values[component]) * factor;
return result;
}
@@ -238,59 +90,133 @@ static Color ReadTexel(const uint8_t* src,
uint32_t z)
{
const uint64_t offset = (uint64_t)z * slice_pitch + (uint64_t)y * row_pitch + (uint64_t)x * texel_size;
return ReadUnorm8(src + (size_t)offset, format);
return PhiReadBlitFloat4(src + (size_t)offset, format);
}
static inline Color PrepareLinearSample(Color color,
const PhiCmdBlitImage* command,
const FormatInfo* src_info,
int* apply_srgb_conversion)
{
if(command->allow_srgb_conversion && src_info->is_srgb)
{
*apply_srgb_conversion = 0;
return PhiConvertBlitFloat4(color, (PhiFormat)command->src_format, (PhiFormat)command->dst_format, 1, 1);
}
return color;
}
static Color
Sample(const uint8_t* src, const PhiCmdBlitImage* command, uint32_t texel_size, float x, float y, float z, int filter_3d)
Sample(const uint8_t* src, const PhiCmdBlitImage* command, const FormatInfo* src_info, float x, float y, float z, int filter_3d)
{
const PhiFormat format = (PhiFormat)command->src_format;
int apply_srgb_conversion = 1;
if(command->filter == PHI_FILTER_NEAREST)
{
return ReadTexel(src,
format,
texel_size,
command->src_row_pitch,
command->src_slice_pitch,
GetNearestCoordinate(x, command->src_width),
GetNearestCoordinate(y, command->src_height),
GetNearestCoordinate(z, command->src_depth));
Color color = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
GetNearestCoordinate(x, command->src_width),
GetNearestCoordinate(y, command->src_height),
GetNearestCoordinate(z, command->src_depth));
return PhiConvertBlitFloat4(color, format, (PhiFormat)command->dst_format, command->allow_srgb_conversion, 1);
}
const SampleCoordinate sample_x = GetLinearCoordinate(x, command->src_width);
const SampleCoordinate sample_y = GetLinearCoordinate(y, command->src_height);
const SampleCoordinate sample_z = GetLinearCoordinate(z, command->src_depth);
const Color color_0_0 = ReadTexel(
src, format, texel_size, command->src_row_pitch, command->src_slice_pitch, sample_x.lo, sample_y.lo, sample_z.lo);
const Color color_0_1 = ReadTexel(
src, format, texel_size, command->src_row_pitch, command->src_slice_pitch, sample_x.hi, sample_y.lo, sample_z.lo);
const Color color_1_0 = ReadTexel(
src, format, texel_size, command->src_row_pitch, command->src_slice_pitch, sample_x.lo, sample_y.hi, sample_z.lo);
const Color color_1_1 = ReadTexel(
src, format, texel_size, command->src_row_pitch, command->src_slice_pitch, sample_x.hi, sample_y.hi, sample_z.lo);
Color color_0_0 = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
sample_x.lo,
sample_y.lo,
sample_z.lo);
Color color_0_1 = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
sample_x.hi,
sample_y.lo,
sample_z.lo);
Color color_1_0 = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
sample_x.lo,
sample_y.hi,
sample_z.lo);
Color color_1_1 = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
sample_x.hi,
sample_y.hi,
sample_z.lo);
color_0_0 = PrepareLinearSample(color_0_0, command, src_info, &apply_srgb_conversion);
color_0_1 = PrepareLinearSample(color_0_1, command, src_info, &apply_srgb_conversion);
color_1_0 = PrepareLinearSample(color_1_0, command, src_info, &apply_srgb_conversion);
color_1_1 = PrepareLinearSample(color_1_1, command, src_info, &apply_srgb_conversion);
const Color row_0 = LerpColor(color_0_0, color_0_1, sample_x.factor);
const Color row_1 = LerpColor(color_1_0, color_1_1, sample_x.factor);
const Color slice_0 = LerpColor(row_0, row_1, sample_y.factor);
if(!filter_3d)
return slice_0;
return PhiConvertBlitFloat4(
slice_0, format, (PhiFormat)command->dst_format, command->allow_srgb_conversion, apply_srgb_conversion);
const Color color_0_0_1 = ReadTexel(
src, format, texel_size, command->src_row_pitch, command->src_slice_pitch, sample_x.lo, sample_y.lo, sample_z.hi);
const Color color_0_1_1 = ReadTexel(
src, format, texel_size, command->src_row_pitch, command->src_slice_pitch, sample_x.hi, sample_y.lo, sample_z.hi);
const Color color_1_0_1 = ReadTexel(
src, format, texel_size, command->src_row_pitch, command->src_slice_pitch, sample_x.lo, sample_y.hi, sample_z.hi);
const Color color_1_1_1 = ReadTexel(
src, format, texel_size, command->src_row_pitch, command->src_slice_pitch, sample_x.hi, sample_y.hi, sample_z.hi);
Color color_0_0_1 = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
sample_x.lo,
sample_y.lo,
sample_z.hi);
Color color_0_1_1 = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
sample_x.hi,
sample_y.lo,
sample_z.hi);
Color color_1_0_1 = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
sample_x.lo,
sample_y.hi,
sample_z.hi);
Color color_1_1_1 = ReadTexel(src,
format,
src_info->texel_size,
command->src_row_pitch,
command->src_slice_pitch,
sample_x.hi,
sample_y.hi,
sample_z.hi);
color_0_0_1 = PrepareLinearSample(color_0_0_1, command, src_info, &apply_srgb_conversion);
color_0_1_1 = PrepareLinearSample(color_0_1_1, command, src_info, &apply_srgb_conversion);
color_1_0_1 = PrepareLinearSample(color_1_0_1, command, src_info, &apply_srgb_conversion);
color_1_1_1 = PrepareLinearSample(color_1_1_1, command, src_info, &apply_srgb_conversion);
const Color row_0_1 = LerpColor(color_0_0_1, color_0_1_1, sample_x.factor);
const Color row_1_1 = LerpColor(color_1_0_1, color_1_1_1, sample_x.factor);
const Color slice_1 = LerpColor(row_0_1, row_1_1, sample_y.factor);
return LerpColor(slice_0, slice_1, sample_z.factor);
Color color = LerpColor(slice_0, slice_1, sample_z.factor);
return PhiConvertBlitFloat4(
color, format, (PhiFormat)command->dst_format, command->allow_srgb_conversion, apply_srgb_conversion);
}
static inline int IsMemoryRangeValid(const Memory* memory, uint64_t offset, uint64_t size)
@@ -425,13 +351,26 @@ static inline void BlitScalarPixel(uint8_t* dst,
const uint8_t* src,
const PhiCmdBlitImage* command,
const FormatInfo* src_info,
const FormatInfo* dst_info,
float source_x,
float source_y,
float source_z,
int filter_3d)
{
const Color color = Sample(src, command, src_info->texel_size, source_x, source_y, source_z, filter_3d);
WriteUnorm8(dst, (PhiFormat)command->dst_format, color);
if(src_info->is_integer && dst_info->is_integer)
{
const uint32_t x = GetNearestCoordinate(source_x, command->src_width);
const uint32_t y = GetNearestCoordinate(source_y, command->src_height);
const uint32_t z = GetNearestCoordinate(source_z, command->src_depth);
const uint64_t offset =
(uint64_t)z * command->src_slice_pitch + (uint64_t)y * command->src_row_pitch + (uint64_t)x * src_info->texel_size;
const PhiBlitInt4 color = PhiReadBlitInt4(src + (size_t)offset, (PhiFormat)command->src_format);
PhiWriteBlitInt4(color, dst, (PhiFormat)command->dst_format);
return;
}
const Color color = Sample(src, command, src_info, source_x, source_y, source_z, filter_3d);
PhiWriteBlitFloat4(color, dst, (PhiFormat)command->dst_format);
}
static void BlitRow(uint8_t* dst,
@@ -448,7 +387,8 @@ static void BlitRow(uint8_t* dst,
// Fast path
if(command->filter == PHI_FILTER_NEAREST && command->src_format == command->dst_format && command->step_x == 1.0f &&
first_source_x >= 0.0f && first_source_x + (float)(pixel_count - 1) < (float)command->src_width)
!(command->allow_srgb_conversion && (src_info->is_srgb || dst_info->is_srgb)) && first_source_x >= 0.0f &&
first_source_x + (float)(pixel_count - 1) < (float)command->src_width)
{
const uint32_t source_texel_x = GetNearestCoordinate(first_source_x, command->src_width);
const uint32_t source_texel_y = GetNearestCoordinate(source_y, command->src_height);
@@ -461,13 +401,14 @@ static void BlitRow(uint8_t* dst,
}
uint32_t processed = 0;
if(src_info->texel_size == 4 && dst_info->texel_size == 4 && command->src_width <= INT32_MAX)
if(src_info->vector_unorm8x4 && dst_info->vector_unorm8x4 && command->src_width <= INT32_MAX)
{
while(processed < pixel_count && ((uintptr_t)(dst + (size_t)processed * 4) & 63) != 0)
{
const int32_t destination_x = command->dst_x0 + (int32_t)processed;
const float source_x = command->src_x0 + (float)destination_x * command->step_x;
BlitScalarPixel(dst + (size_t)processed * 4, src, command, src_info, source_x, source_y, source_z, filter_3d);
BlitScalarPixel(
dst + (size_t)processed * 4, src, command, src_info, dst_info, source_x, source_y, source_z, filter_3d);
++processed;
}
@@ -536,8 +477,15 @@ static void BlitRow(uint8_t* dst,
{
const int32_t destination_x = command->dst_x0 + (int32_t)processed;
const float source_x = command->src_x0 + (float)destination_x * command->step_x;
BlitScalarPixel(
dst + (size_t)processed * dst_info->texel_size, src, command, src_info, source_x, source_y, source_z, filter_3d);
BlitScalarPixel(dst + (size_t)processed * dst_info->texel_size,
src,
command,
src_info,
dst_info,
source_x,
source_y,
source_z,
filter_3d);
++processed;
}
}
@@ -581,12 +529,21 @@ PhiStatus BlitImage(const PhiCmdBlitImage* command)
FormatInfo src_info;
FormatInfo dst_info;
if(!GetFormatInfo((PhiFormat)command->src_format, &src_info) || !GetFormatInfo((PhiFormat)command->dst_format, &dst_info))
if(!PhiGetBlitFormatInfo((PhiFormat)command->src_format, &src_info) ||
!PhiGetBlitFormatInfo((PhiFormat)command->dst_format, &dst_info))
{
LogErrorFmt("Unsupported blit image formats: src=%u dst=%u", command->src_format, command->dst_format);
return PHI_STATUS_INVALID_ARGUMENT;
}
const int integer_path = src_info.is_integer && dst_info.is_integer;
if((integer_path && (!src_info.can_read_int || !dst_info.can_write_int)) ||
(!integer_path && (!src_info.can_read_float || !dst_info.can_write_float)))
{
LogErrorFmt("Unsupported blit image format direction: src=%u dst=%u", command->src_format, command->dst_format);
return PHI_STATUS_INVALID_ARGUMENT;
}
PhiStatus status = ValidateCommand(command, src_memory, dst_memory, &src_info, &dst_info);
if(status != PHI_STATUS_OK)
return status;
+1 -1
View File
@@ -7,7 +7,7 @@
#include <string.h>
static const char* CommandName[] = {
"CopyBuffer", "FillBuffer", "CopyBufferToImage", "CopyImageToBuffer", "CopyImage",
"CopyBuffer", "FillBuffer", "CopyBufferToImage", "CopyImageToBuffer", "CopyImage", "BlitImage",
};
PhiStatus ReadCommandData(PhiCommandReader* reader, void* data, uint64_t size)
+29 -11
View File
@@ -82,7 +82,9 @@ int HandleNewMemory(PhiEndpoint endpoint, const PhiMessageHeader* header)
if(memory == NULL)
LogErrorFmt("Failed to allocate %zu bytes", (size_t)request.size);
else
LogInfoFmt("Allocated %llu bytes to handle 0x%X", request.size, (uintptr_t)memory);
LogInfoFmt("Allocated %llu bytes to handle 0x%llX",
(unsigned long long)request.size,
(unsigned long long)(uintptr_t)memory);
}
else if(header->type == PHI_PACKET_MAP_HOST_MEMORY)
{
@@ -93,7 +95,7 @@ int HandleNewMemory(PhiEndpoint endpoint, const PhiMessageHeader* header)
if(memory == NULL)
reply.result.status = PHI_STATUS_MAP_HOST_MEMORY_FAILED;
else
LogInfoFmt("Mapped host memory to handle 0x%X", (uint64_t)(uintptr_t)memory);
LogInfoFmt("Mapped host memory to handle 0x%llX", (unsigned long long)(uintptr_t)memory);
}
if(memory != NULL)
@@ -131,20 +133,36 @@ int HandleDestroyMemory(PhiEndpoint endpoint, const PhiMessageHeader* header)
if(request.remote_handle == 0)
{
reply.result.status = PHI_STATUS_INVALID_HANDLE;
LogErrorFmt("Could not free memory: invalid handle 0x%X", request.remote_handle);
LogErrorFmt("Could not free memory: invalid handle 0x%llX", (unsigned long long)request.remote_handle);
}
else
{
const Memory* memory = (const Memory*)(uintptr_t)request.remote_handle;
Memory* memory = (Memory*)(uintptr_t)request.remote_handle;
const MemoryType memory_type = memory->type;
const char* memory_type_name;
if(memory->type == PHI_MEMORY_LOCAL)
free((void*)memory);
else if(memory->type == PHI_MEMORY_HOST_MAPPED)
scif_munmap((void*)memory->ptr, memory->size);
if(memory_type == PHI_MEMORY_LOCAL)
memory_type_name = "local";
else if(memory_type == PHI_MEMORY_HOST_MAPPED)
memory_type_name = "host-mapped";
else
{
reply.result.status = PHI_STATUS_INVALID_HANDLE;
LogErrorFmt("Could not free memory handle 0x%llX: invalid memory type", (unsigned long long)request.remote_handle);
return SendReply(endpoint, header, &reply, sizeof(reply));
}
LogInfoFmt("Destroyed %s memory handle 0x%X",
memory->type == PHI_MEMORY_LOCAL ? "local" : "host-mapped",
request.remote_handle);
if(memory_type == PHI_MEMORY_HOST_MAPPED && scif_munmap(memory->ptr, (size_t)memory->scif_size) != 0)
{
reply.result.status = PHI_STATUS_INVALID_HANDLE;
LogErrorFmt("Failed to unmap memory handle 0x%llX: %s", (unsigned long long)request.remote_handle, strerror(errno));
}
else
{
LogInfoFmt("Destroyed %s memory handle 0x%llX", memory_type_name, (unsigned long long)request.remote_handle);
}
free(memory);
}
return SendReply(endpoint, header, &reply, sizeof(reply));
+25 -14
View File
@@ -49,16 +49,21 @@ static int SendQueueCompletion(PhiEndpoint endpoint, uint64_t sequence, PhiStatu
static int RunQueue(PhiEndpoint endpoint, volatile PhiQueueShared* shared)
{
uint64_t next_sequence = 1;
PhiStatus fatal_status = PHI_STATUS_OK;
for(;;)
{
PhiQueueDoorbell doorbell;
if(ReadAll(endpoint, &doorbell, sizeof(doorbell)) < 0)
{
LogWarningFmt("Queue peer disconnected while waiting for sequence %llu", (unsigned long long)next_sequence);
return 0;
}
if(doorbell.sequence == PHI_QUEUE_SHUTDOWN_SEQUENCE)
{
LogInfoFmt("Received queue shutdown doorbell at sequence %llu", (unsigned long long)next_sequence);
return 1;
}
if(doorbell.sequence < next_sequence)
continue;
@@ -76,20 +81,14 @@ static int RunQueue(PhiEndpoint endpoint, volatile PhiQueueShared* shared)
.command_count = remote_submission->command_count,
};
PhiStatus status = fatal_status;
if(status == PHI_STATUS_OK)
{
if(submission.sequence != next_sequence)
status = PHI_STATUS_BAD_MESSAGE;
else
status = ExecuteQueueSubmission(endpoint, &submission);
}
PhiStatus status;
if(submission.sequence != next_sequence)
status = PHI_STATUS_BAD_MESSAGE;
else
status = ExecuteQueueSubmission(endpoint, &submission);
if(status != PHI_STATUS_OK && fatal_status == PHI_STATUS_OK)
{
if(status != PHI_STATUS_OK)
LogErrorFmt("Queue submission %llu failed: %s", (unsigned long long)next_sequence, StatusName[status]);
fatal_status = status;
}
__atomic_store_n(&shared->completed_sequence, next_sequence, __ATOMIC_RELEASE);
if(SendQueueCompletion(endpoint, next_sequence, status) < 0)
@@ -143,10 +142,22 @@ int HandleQueueSetup(PhiEndpoint endpoint, const PhiMessageHeader* header)
const int run_result = RunQueue(endpoint, shared);
if(scif_munmap((void*)shared, (size_t)request.scif_size) != 0)
{
LogErrorFmt("Failed to unmap queue ring during shutdown: %s", strerror(errno));
return -1;
}
if(run_result == 1)
return SendQueueCompletion(endpoint, PHI_QUEUE_SHUTDOWN_SEQUENCE, PHI_STATUS_OK);
{
LogInfo("Queue ring unmapped; sending shutdown acknowledgement");
if(SendQueueCompletion(endpoint, PHI_QUEUE_SHUTDOWN_SEQUENCE, PHI_STATUS_OK) < 0)
{
LogErrorFmt("Failed to send queue shutdown acknowledgement: %s", strerror(errno));
return -1;
}
LogInfo("Queue shutdown acknowledgement sent");
return 0;
}
return run_result;
}