| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Copyright 2013 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "OCLTextureDecoder.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-31 06:08:46 +00:00
										 |  |  | #include "../OpenCL.h"
 | 
					
						
							| 
									
										
										
										
											2013-09-12 03:44:16 +02:00
										 |  |  | #include "CommonPaths.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | #include "FileUtil.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <string>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //#define DEBUG_OPENCL
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | cl_program g_program; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct sDecoderParameter | 
					
						
							| 
									
										
										
										
											2010-06-26 13:12:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | 	const char *name; | 
					
						
							|  |  |  | 	cl_kernel kernel; | 
					
						
							|  |  |  | 	float sizeOfSrc; | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 	float sizeOfDst; | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | 	int xSkip; | 
					
						
							|  |  |  | 	int ySkip; | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 	PC_TexFormat format; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | sDecoderParameter g_DecodeParametersNative[] = { | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | 	/* GX_TF_I4     */ { "DecodeI4",     NULL, 0.5f, 1, 8, 8, PC_TEX_FMT_I4_AS_I8 }, | 
					
						
							|  |  |  | 	/* GX_TF_I8     */ { "DecodeI8",     NULL,    1, 1, 8, 4, PC_TEX_FMT_I8 }, | 
					
						
							|  |  |  | 	/* GX_TF_IA4    */ { "DecodeIA4",    NULL,    1, 2, 8, 4, PC_TEX_FMT_IA4_AS_IA8 }, | 
					
						
							|  |  |  | 	/* GX_TF_IA8    */ { "DecodeIA8",    NULL,    2, 2, 4, 4, PC_TEX_FMT_IA8 }, | 
					
						
							|  |  |  | 	/* GX_TF_RGB565 */ { "DecodeRGB565", NULL,    2, 2, 4, 4, PC_TEX_FMT_RGB565 }, | 
					
						
							|  |  |  | 	/* GX_TF_RGB5A3 */ { "DecodeRGB5A3", NULL,    2, 4, 4, 4, PC_TEX_FMT_BGRA32 }, | 
					
						
							|  |  |  | 	/* GX_TF_RGBA8  */ { "DecodeRGBA8",  NULL,    4, 4, 4, 4, PC_TEX_FMT_BGRA32 }, | 
					
						
							| 
									
										
										
										
											2011-02-14 21:58:53 +00:00
										 |  |  | 	/* 7            */ { NULL,           NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* GX_TF_C4     */ { NULL,           NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* GX_TF_C8     */ { NULL,           NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* GX_TF_C14X2  */ { NULL,           NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* B            */ { NULL,           NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* C            */ { NULL,           NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* D            */ { NULL,           NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | 	/* GX_TF_CMPR   */ { "DecodeCMPR",   NULL, 0.5f, 4, 8, 8, PC_TEX_FMT_BGRA32 }, | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sDecoderParameter g_DecodeParametersRGBA[] = { | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | 	/* GX_TF_I4     */ { "DecodeI4_RGBA",     NULL, 0.5f, 4, 8, 8, PC_TEX_FMT_RGBA32 }, | 
					
						
							|  |  |  | 	/* GX_TF_I8     */ { "DecodeI8_RGBA",     NULL,    1, 4, 8, 4, PC_TEX_FMT_RGBA32 }, | 
					
						
							|  |  |  | 	/* GX_TF_IA4    */ { "DecodeIA4_RGBA",    NULL,    1, 4, 8, 4, PC_TEX_FMT_RGBA32 }, | 
					
						
							|  |  |  | 	/* GX_TF_IA8    */ { "DecodeIA8_RGBA",    NULL,    2, 4, 4, 4, PC_TEX_FMT_RGBA32 }, | 
					
						
							|  |  |  | 	/* GX_TF_RGB565 */ { "DecodeRGB565_RGBA", NULL,    2, 4, 4, 4, PC_TEX_FMT_RGBA32 }, | 
					
						
							|  |  |  | 	/* GX_TF_RGB5A3 */ { "DecodeRGB5A3_RGBA", NULL,    2, 4, 4, 4, PC_TEX_FMT_RGBA32 }, | 
					
						
							|  |  |  | 	/* GX_TF_RGBA8  */ { "DecodeRGBA8_RGBA",  NULL,    4, 4, 4, 4, PC_TEX_FMT_RGBA32 }, | 
					
						
							| 
									
										
										
										
											2011-02-14 21:58:53 +00:00
										 |  |  | 	/* 7            */ { NULL,                NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* GX_TF_C4     */ { NULL,                NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* GX_TF_C8     */ { NULL,                NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* GX_TF_C14X2  */ { NULL,                NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* B            */ { NULL,                NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* C            */ { NULL,                NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							|  |  |  | 	/* D            */ { NULL,                NULL,    0, 0, 0, 0, PC_TEX_FMT_NONE }, | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | 	/* GX_TF_CMPR   */ { "DecodeCMPR_RGBA",   NULL, 0.5f, 4, 8, 8, PC_TEX_FMT_RGBA32 }, | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool g_Inited = false; | 
					
						
							|  |  |  | cl_mem g_clsrc, g_cldst;                    // texture buffer memory objects
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-01 21:08:30 +00:00
										 |  |  | #define HEADER_SIZE	32
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | void TexDecoder_OpenCL_Initialize() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 	if(!g_Inited) | 
					
						
							| 
									
										
										
										
											2010-06-19 07:59:53 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 		if(!OpenCL::Initialize()) | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 		cl_int err = 1; | 
					
						
							| 
									
										
										
										
											2010-12-19 13:25:57 +00:00
										 |  |  | 		size_t binary_size = 0; | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 		char *binary = NULL; | 
					
						
							|  |  |  | 		char *header = NULL; | 
					
						
							| 
									
										
										
										
											2010-12-19 13:25:57 +00:00
										 |  |  | 		size_t nDevices = 0; | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 		cl_device_id *devices = NULL; | 
					
						
							| 
									
										
										
										
											2010-12-19 13:25:57 +00:00
										 |  |  | 		size_t *binary_sizes = NULL; | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04:00
										 |  |  | 		char **binaries = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-28 20:40:15 +00:00
										 |  |  | 		std::string filename; | 
					
						
							| 
									
										
										
										
											2011-01-01 21:08:30 +00:00
										 |  |  | 		char dolphin_rev[HEADER_SIZE]; | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-28 20:40:15 +00:00
										 |  |  | 		filename = File::GetUserPath(D_OPENCL_IDX) + "kernel.bin"; | 
					
						
							| 
									
										
										
										
											2011-08-21 16:30:19 -05:00
										 |  |  | 		snprintf(dolphin_rev, HEADER_SIZE, "%-31s", scm_rev_str); | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 10:21:46 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 		File::IOFile input(filename, "rb"); | 
					
						
							|  |  |  | 		if (!input) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 			binary_size = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-03-11 10:21:46 +00:00
										 |  |  | 			binary_size = input.GetSize(); | 
					
						
							| 
									
										
										
										
											2012-03-25 13:01:26 +03:00
										 |  |  | 			header = new char[HEADER_SIZE]; | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 			binary = new char[binary_size]; | 
					
						
							| 
									
										
										
										
											2011-03-11 10:21:46 +00:00
										 |  |  | 			input.ReadBytes(header, HEADER_SIZE); | 
					
						
							|  |  |  | 			input.ReadBytes(binary, binary_size); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-06-26 13:12:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 		if (binary_size > 0) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-01-01 21:08:30 +00:00
										 |  |  | 			if (binary_size > HEADER_SIZE) | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-01-01 21:08:30 +00:00
										 |  |  | 				if (strncmp(header, dolphin_rev, HEADER_SIZE) == 0) | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					g_program = clCreateProgramWithBinary(OpenCL::GetContext(), 1, &OpenCL::device_id, &binary_size, (const unsigned char**)&binary, NULL, &err); | 
					
						
							|  |  |  | 					if (err != CL_SUCCESS) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						OpenCL::HandleCLError(err, "clCreateProgramWithBinary"); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-03-19 21:51:12 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 					if (!err) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						err = clBuildProgram(g_program, 1, &OpenCL::device_id, NULL, NULL, NULL); | 
					
						
							|  |  |  | 						if (err != CL_SUCCESS) | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							OpenCL::HandleCLError(err, "clBuildProgram"); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 19:41:13 +02:00
										 |  |  | 			delete [] header; | 
					
						
							|  |  |  | 			delete [] binary; | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-19 02:28:49 +00:00
										 |  |  | 		// If an error occurred using the kernel binary, recompile the kernels
 | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 		if (err) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			std::string code; | 
					
						
							| 
									
										
										
										
											2013-09-12 03:44:16 +02:00
										 |  |  | 			filename = File::GetSysDirectory() + OPENCL_DIR DIR_SEP "TextureDecoder.cl"; | 
					
						
							| 
									
										
										
										
											2011-02-28 20:40:15 +00:00
										 |  |  | 			if (!File::ReadFileToString(true, filename.c_str(), code)) | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-02-28 20:40:15 +00:00
										 |  |  | 				ERROR_LOG(VIDEO, "Failed to load OpenCL code %s - file is missing?", filename.c_str()); | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			g_program = OpenCL::CompileProgram(code.c_str()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			err = clGetProgramInfo(g_program, CL_PROGRAM_NUM_DEVICES, sizeof(nDevices), &nDevices, NULL); | 
					
						
							|  |  |  | 			if (err != CL_SUCCESS) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				OpenCL::HandleCLError(err, "clGetProgramInfo"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			devices = (cl_device_id *)malloc( sizeof(cl_device_id) *nDevices); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			err = clGetProgramInfo(g_program, CL_PROGRAM_DEVICES, sizeof(cl_device_id)*nDevices, devices, NULL); | 
					
						
							|  |  |  | 			if (err != CL_SUCCESS) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				OpenCL::HandleCLError(err, "clGetProgramInfo"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			binary_sizes = (size_t *)malloc(sizeof(size_t)*nDevices); | 
					
						
							|  |  |  | 			err = clGetProgramInfo(g_program, CL_PROGRAM_BINARY_SIZES,	sizeof(size_t)*nDevices, binary_sizes, NULL); | 
					
						
							|  |  |  | 			if (err != CL_SUCCESS) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				OpenCL::HandleCLError(err, "clGetProgramInfo"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			binaries = (char **)malloc(sizeof(char *)*nDevices); | 
					
						
							|  |  |  | 			for (u32 i = 0; i < nDevices; ++i) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-03-19 02:28:49 +00:00
										 |  |  | 				if (binary_sizes[i] != 0) | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2011-01-01 21:08:30 +00:00
										 |  |  | 					binaries[i] = (char *)malloc(HEADER_SIZE + binary_sizes[i]); | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					binaries[i] = NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			err = clGetProgramInfo( g_program, CL_PROGRAM_BINARIES,	sizeof(char *)*nDevices, binaries, NULL ); | 
					
						
							|  |  |  | 			if (err != CL_SUCCESS) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				OpenCL::HandleCLError(err, "clGetProgramInfo"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!err) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-02-28 20:40:15 +00:00
										 |  |  | 				filename = File::GetUserPath(D_OPENCL_IDX) + "kernel.bin"; | 
					
						
							| 
									
										
										
										
											2011-01-01 21:08:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 10:21:46 +00:00
										 |  |  | 				File::IOFile output(filename, "wb"); | 
					
						
							|  |  |  | 				if (!output) | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					binary_size = 0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					// Supporting one OpenCL device for now
 | 
					
						
							| 
									
										
										
										
											2011-03-11 10:21:46 +00:00
										 |  |  | 					output.WriteBytes(dolphin_rev, HEADER_SIZE); | 
					
						
							|  |  |  | 					output.WriteBytes(binaries[0], binary_sizes[0]); | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-03-19 02:28:49 +00:00
										 |  |  | 			for (u32 i = 0; i < nDevices; ++i) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-03-20 18:35:07 +00:00
										 |  |  | 				if (binary_sizes[i] != 0) | 
					
						
							| 
									
										
										
										
											2011-03-19 02:28:49 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					free(binaries[i]); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (binaries != NULL) | 
					
						
							|  |  |  | 				free(binaries); | 
					
						
							|  |  |  | 			if (binary_sizes != NULL) | 
					
						
							|  |  |  | 				free(binary_sizes); | 
					
						
							|  |  |  | 			if (devices != NULL) | 
					
						
							|  |  |  | 				free(devices); | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-19 02:28:49 +00:00
										 |  |  | 		for (int i = 0; i <= GX_TF_CMPR; ++i) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2010-06-26 13:12:28 +00:00
										 |  |  | 			if (g_DecodeParametersNative[i].name) | 
					
						
							|  |  |  | 				g_DecodeParametersNative[i].kernel = | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 				OpenCL::CompileKernel(g_program, | 
					
						
							|  |  |  | 				g_DecodeParametersNative[i].name); | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-26 13:12:28 +00:00
										 |  |  | 			if (g_DecodeParametersRGBA[i].name) | 
					
						
							|  |  |  | 				g_DecodeParametersRGBA[i].kernel = | 
					
						
							| 
									
										
										
										
											2010-12-19 11:03:09 +00:00
										 |  |  | 				OpenCL::CompileKernel(g_program, | 
					
						
							|  |  |  | 				g_DecodeParametersRGBA[i].name); | 
					
						
							| 
									
										
										
										
											2010-06-26 13:12:28 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Allocating maximal Wii texture size in advance, so that we don't have to allocate/deallocate per texture
 | 
					
						
							|  |  |  | #ifndef DEBUG_OPENCL
 | 
					
						
							|  |  |  | 		g_clsrc = clCreateBuffer(OpenCL::GetContext(), CL_MEM_READ_ONLY , 1024 * 1024 * sizeof(u32), NULL, NULL); | 
					
						
							|  |  |  | 		g_cldst = clCreateBuffer(OpenCL::GetContext(), CL_MEM_WRITE_ONLY, 1024 * 1024 * sizeof(u32), NULL, NULL); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		g_Inited = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | void TexDecoder_OpenCL_Shutdown() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-24 04:17:36 +00:00
										 |  |  | 	if (g_program) | 
					
						
							|  |  |  | 		clReleaseProgram(g_program); | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-26 13:12:28 +00:00
										 |  |  | 	for (int i = 0; i < GX_TF_CMPR; ++i) { | 
					
						
							|  |  |  | 		if (g_DecodeParametersNative[i].kernel) | 
					
						
							|  |  |  | 			clReleaseKernel(g_DecodeParametersNative[i].kernel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(g_DecodeParametersRGBA[i].kernel) | 
					
						
							|  |  |  | 			clReleaseKernel(g_DecodeParametersRGBA[i].kernel); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 	if(g_clsrc) | 
					
						
							|  |  |  | 		clReleaseMemObject(g_clsrc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(g_cldst) | 
					
						
							|  |  |  | 		clReleaseMemObject(g_cldst); | 
					
						
							| 
									
										
										
										
											2010-06-26 13:12:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 	g_Inited = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | PC_TexFormat TexDecoder_Decode_OpenCL(u8 *dst, const u8 *src, int width, int height, int texformat, int tlutaddr, int tlutfmt, bool rgba) | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-19 07:59:53 +00:00
										 |  |  | 	cl_int err; | 
					
						
							| 
									
										
										
										
											2010-07-06 13:14:51 +00:00
										 |  |  | 	sDecoderParameter& decoder = rgba ? g_DecodeParametersRGBA[texformat] : g_DecodeParametersNative[texformat]; | 
					
						
							|  |  |  | 	if(!g_Inited || !decoder.name || !decoder.kernel || decoder.format == PC_TEX_FMT_NONE) | 
					
						
							|  |  |  | 		return PC_TEX_FMT_NONE; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_OPENCL
 | 
					
						
							|  |  |  | 	g_clsrc = clCreateBuffer(OpenCL::GetContext(), CL_MEM_READ_ONLY , 1024 * 1024 * sizeof(u32), NULL, NULL); | 
					
						
							|  |  |  | 	g_cldst = clCreateBuffer(OpenCL::GetContext(), CL_MEM_WRITE_ONLY, 1024 * 1024 * sizeof(u32), NULL, NULL); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 	clEnqueueWriteBuffer(OpenCL::GetCommandQueue(), g_clsrc, CL_TRUE, 0, (size_t)(width * height * decoder.sizeOfSrc), src, 0, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 	clSetKernelArg(decoder.kernel, 0, sizeof(cl_mem), &g_cldst); | 
					
						
							|  |  |  | 	clSetKernelArg(decoder.kernel, 1, sizeof(cl_mem), &g_clsrc); | 
					
						
							|  |  |  | 	clSetKernelArg(decoder.kernel, 2, sizeof(cl_int), &width); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 	size_t global[] = { (size_t)(width / decoder.xSkip), (size_t)(height / decoder.ySkip) }; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// No work-groups for now
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	size_t local; | 
					
						
							|  |  |  | 	err = clGetKernelWorkGroupInfo(kernelToRun, OpenCL::device_id, CL_KERNEL_WORK_GROUP_SIZE, sizeof(local), &local, NULL); | 
					
						
							|  |  |  | 	if(err) | 
					
						
							|  |  |  | 		PanicAlert("Error obtaining work-group information"); | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 	err = clEnqueueNDRangeKernel(OpenCL::GetCommandQueue(), decoder.kernel, 2, NULL, global, NULL, 0, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 	if(err) | 
					
						
							| 
									
										
										
										
											2010-06-19 07:59:53 +00:00
										 |  |  | 		OpenCL::HandleCLError(err, "Failed to enqueue kernel"); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	clFinish(OpenCL::GetCommandQueue()); | 
					
						
							| 
									
										
										
										
											2010-06-26 13:12:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 	clEnqueueReadBuffer(OpenCL::GetCommandQueue(), g_cldst, CL_TRUE, 0, (size_t)(width * height * decoder.sizeOfDst), dst, 0, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG_OPENCL
 | 
					
						
							|  |  |  | 	clReleaseMemObject(g_clsrc); | 
					
						
							|  |  |  | 	clReleaseMemObject(g_cldst); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 00:52:17 +00:00
										 |  |  | 	return decoder.format; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } |