#include <mil.h>
#include <milfpga.h>
#include <fpga_lutmap.h>
#define FUNCTION_NB_PARAM_LOAD_LUT 1
#define FUNCTION_OPCODE_FPGA_LOAD_LUT 3
#define FUNCTION_NB_PARAM_LUT_MAP 3
#define FUNCTION_OPCODE_FPGA_LUT_MAP 6
#define FUNCTION_PARAMETER_ERROR_CODE 1
#define FUNCTION_WRONG_FPGA_ERROR_CODE 2
void FPGALoadLut(MIL_ID LutId);
void MFTYPE FPGALoadLutSlave(MIL_ID Func);
void FPGALoadLutPrimitive(MIL_ID Func, MIL_ID MilLut);
void FPGALutMap(MIL_ID SrcImageId, MIL_ID DstImageId, MIL_ID LutId);
void MFTYPE FPGALutMapSlave(MIL_ID Func);
void FPGALutMapPrimitive(MIL_ID Func, MIL_ID SrcImageId, MIL_ID DstImageId, MIL_ID LutId);
void FPGAInitializeShadowRegisters(MIL_ID Func, FPGA_LUTMAP_USER_ST*pLMShadow,
MIL_BUFFER_INFO Src, MIL_BUFFER_INFO Dst, MIL_BUFFER_INFO Lut);
void FPGALoadLutPrimitive(MIL_ID Func, MIL_ID LutId)
{
MIL_BUFFER_INFO Lut;
MIL_FPGA_CONTEXT LutMapContext;
FPGA_LUTMAP_USER_ST LMShadow;
memset(&LMShadow, 0, sizeof(LMShadow));
MfuncInquire(LutId, M_BUFFER_INFO, &Lut);
if(MfpgaCommandAlloc(MfuncBufOwnerSystemId(Lut), M_DEV0, FPGA_LUTMAP_FID,
M_DEFAULT, M_DEV0, M_ASYNCHRONOUS, M_DEFAULT, &LutMapContext))
{
switch(MfuncBufSizeX(Lut))
{
case 256:
LMShadow.ctrl.f.lutbits = 0; break;
case 512:
LMShadow.ctrl.f.lutbits = 1; break;
case 1024:
LMShadow.ctrl.f.lutbits = 2; break;
case 2048:
LMShadow.ctrl.f.lutbits = 3; break;
case 4096:
LMShadow.ctrl.f.lutbits = 4; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_PARAMETER_ERROR_CODE,
MIL_TEXT("Invalid LUT depth."),
M_NULL, M_NULL, M_NULL
);
}
LMShadow.ctrl.f.mode = 0;
MfpgaSetSource(LutMapContext, Lut, M_INPUT0, M_DEFAULT);
MfpgaSetRegister(LutMapContext, M_USER, 0, sizeof(LMShadow),
(void*)(&LMShadow), M_WHEN_DISPATCHED);
MfpgaCommandQueue(LutMapContext, M_DEFAULT, M_DEFAULT);
MfpgaCommandFree(LutMapContext, M_DEFAULT);
}
else
{
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("No LutMap acceleration supported by this FPGA configuration."),
MIL_TEXT("Please select the proper FPGA configuration file."),
MIL_TEXT("See the processing FPGA section of the milconfig utility."),
M_NULL
);
}
}
void FPGALutMapPrimitive(MIL_ID Func, MIL_ID SrcImageId, MIL_ID DstImageId, MIL_ID LutId)
{
MIL_BUFFER_INFO Src, Lut, Dst;
MIL_FPGA_CONTEXT LutMapContext;
FPGA_LUTMAP_USER_ST LMShadow;
memset(&LMShadow, 0, sizeof(LMShadow));
MfuncInquire(SrcImageId, M_BUFFER_INFO, &Src);
MfuncInquire(LutId, M_BUFFER_INFO, &Lut);
MfuncInquire(DstImageId, M_BUFFER_INFO, &Dst);
if(MfpgaCommandAlloc(MfuncBufOwnerSystemId(Src), M_DEV0, FPGA_LUTMAP_FID,
M_DEFAULT, M_DEV0, M_ASYNCHRONOUS, M_DEFAULT, &LutMapContext))
{
FPGAInitializeShadowRegisters(Func, &LMShadow, Src, Dst, Lut);
MfpgaSetSource(LutMapContext, Src, M_INPUT0, M_DEFAULT);
MfpgaSetDestination(LutMapContext, Dst, M_OUTPUT0, M_DEFAULT);
MfpgaSetRegister(LutMapContext, M_USER, 0, sizeof(LMShadow),
(void*)(&LMShadow), M_WHEN_DISPATCHED);
MfpgaCommandQueue(LutMapContext, M_DEFAULT, M_DEFAULT);
MfpgaCommandFree(LutMapContext, M_DEFAULT);
}
else
{
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_WRONG_FPGA_ERROR_CODE,
MIL_TEXT("No LutMap acceleration supported by this FPGA configuration."),
MIL_TEXT("Please select the proper FPGA configuration file."),
MIL_TEXT("See the processing FPGA section of the milconfig utility."),
M_NULL
);
}
}
void FPGAInitializeShadowRegisters( MIL_ID Func,
FPGA_LUTMAP_USER_ST* pLMShadow,
MIL_BUFFER_INFO Src,
MIL_BUFFER_INFO Dst,
MIL_BUFFER_INFO Lut)
{
switch(MfuncBufSizeBit(Dst))
{
case 8:
pLMShadow->ctrl.f.dsttype = 0; break;
case 16:
pLMShadow->ctrl.f.dsttype = 1; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_PARAMETER_ERROR_CODE,
MIL_TEXT("Invalid destination buffer type."),
M_NULL, M_NULL, M_NULL
);
break;
}
switch(MfuncBufSizeBit(Src))
{
case 8:
pLMShadow->ctrl.f.srctype = 0; break;
case 16:
pLMShadow->ctrl.f.srctype = 1; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_PARAMETER_ERROR_CODE,
MIL_TEXT("Invalid source buffer type."),
M_NULL, M_NULL, M_NULL
);
break;
}
switch(MfuncBufSizeX(Lut))
{
case 256:
pLMShadow->ctrl.f.lutbits = 0; break;
case 512:
pLMShadow->ctrl.f.lutbits = 1; break;
case 1024:
pLMShadow->ctrl.f.lutbits = 2; break;
case 2048:
pLMShadow->ctrl.f.lutbits = 3; break;
case 4096:
pLMShadow->ctrl.f.lutbits = 4; break;
default:
MfuncErrorReport(
Func, M_FUNC_ERROR+FUNCTION_PARAMETER_ERROR_CODE,
MIL_TEXT("Invalid lut depth."),
M_NULL, M_NULL, M_NULL
);
break;
}
pLMShadow->ctrl.f.mode = 1;
}
void FPGALoadLut(MIL_ID LutId)
{
MIL_ID Func;
MfuncAlloc(MIL_TEXT("FPGALoadLut"),
FUNCTION_NB_PARAM_LOAD_LUT,
FPGALoadLutSlave, M_NULL, M_NULL,
M_USER_MODULE_1+FUNCTION_OPCODE_FPGA_LOAD_LUT,
M_DEFAULT,
&Func
);
MfuncParamMilId(Func, 1, LutId, M_LUT, M_IN);
MfuncCall(Func);
MfuncFree(Func);
}
void MFTYPE FPGALoadLutSlave(MIL_ID Func)
{
MIL_ID LutId;
MfuncParamValue(Func, 1, &LutId);
FPGALoadLutPrimitive(Func, LutId);
}
void FPGALutMap(MIL_ID SrcImageId, MIL_ID DstImageId, MIL_ID LutId)
{
MIL_ID Func;
MfuncAlloc(MIL_TEXT("FPGALutMap"),
FUNCTION_NB_PARAM_LUT_MAP,
FPGALutMapSlave, M_NULL, M_NULL,
M_USER_MODULE_1+FUNCTION_OPCODE_FPGA_LUT_MAP,
M_DEFAULT,
&Func
);
MfuncParamMilId(Func, 1, SrcImageId, M_IMAGE, M_IN);
MfuncParamMilId(Func, 2, DstImageId, M_IMAGE, M_OUT);
MfuncParamMilId(Func, 3, LutId, M_LUT, M_IN);
MfuncCall(Func);
MfuncFree(Func);
}
void MFTYPE FPGALutMapSlave(MIL_ID Func)
{
MIL_ID SrcImageId, LutId, DstImageId;
MfuncParamValue(Func, 1, &SrcImageId);
MfuncParamValue(Func, 2, &DstImageId);
MfuncParamValue(Func, 3, &LutId);
FPGALutMapPrimitive(Func, SrcImageId, DstImageId, LutId);
}