diff --git a/README.md b/README.md index a73a97a..37a940f 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -# AviSynth Shader v1.2.2 +# AviSynth Shader v1.3 Download here >> This plugin allows running HLSL pixel shaders within AviSynth. This gives access to various HLSL filters that haven't been programmed in AviSynth. -This implementation allows running several shaders in a row. Shader() returns a clip containing commands, and each subsequent to Shader() adds a line to that command chain clip. You must call ExecuteShader() to execute the chain of commands. You must also call ConvertToFloat() before and ConvertFromFloat() at the end. +This implementation allows running several shaders in a row. Shader() returns a clip containing commands, and each subsequent to Shader() adds a line to that command chain clip. You must call ExecuteShader() to execute the chain of commands. You must also call ConvertToShader() before and ConvertFromShader() at the end. The following example will run Diff1 and Diff2 on the clip before returning a Merge of both results. (these shader names are fictive, you have to use real shaders!) - ConvertToFloat() - input - Shader("Diff1.cso", output=2) - Shader("Diff2.cso", output=3) - Shader("Merge.cso", clip1=2, clip2=3, output=1) - ShaderExecute(input) - ConvertFromFloat() + ConvertToShader() + Input + Shader("Diff1.cso", Output=2) + Shader("Diff2.cso", Output=3) + Shader("Merge.cso", Clip1=2, Clip2=3, Output=1) + ShaderExecute(last, Input, PrecisionIn=1, Precision=3, PrecisionOut=1) + ConvertFromShader() ## Syntax: -#### ConvertToFloat(input, convertYuv, precision) +#### ConvertToShader(Input, Precision) Converts a YV12, YV24 or RGB32 clip into a wider frame containing UINT16 or half-float data. Clips must be converted in such a way before running any shader. @@ -26,51 +26,47 @@ Converts a YV12, YV24 or RGB32 clip into a wider frame containing UINT16 or half Arguments: -convertYuv: True to convert RGB data to YUV on the CPU. If false, YUV data will be copied as-is and can then be converted with a shader. Default=false. +Precision: 1 to convert into BYTE, 2 to convert into UINT16, 3 to convert into half-float. Default=1 (conversion can be done on the GPU) -precision: 1 to convert into BYTE, 2 to convert into UINT16, 3 to convert into half-float. Default=2 - -#### ConvertFromFloat(input, format, convertYuv, precision) +#### ConvertFromShader(Input, Format, Precision) Convert a half-float clip into a standard YV12, YV24 or RGB32 clip. Arguments: -format: The video format to convert to. Valid formats are YV12, YV24 and RGB32. Default=YV12. - -convertYuv: True to convert YUV data to RGB on the CPU. If false, you already ran a shader to convert to YUV and the data will be copied as-is. Default=false. +Format: The video format to convert to. Valid formats are YV12, YV24 and RGB32. Default=YV12. -precision: 1 to convert into BYTE, 2 to convert into UINT16, 3 to convert into half-float. Default=2 +Precision: 1 to convert into BYTE, 2 to convert into UINT16, 3 to convert into half-float. Default=1 -#### Shader(input, path, entryPoint, shaderModel, param1-param9, clip1-clip9, width, height) +#### Shader(Input, Path, EntryPoint, ShaderModel, Param1-Param9, Clip1-Clip9, Output, Width, Height) Runs a HLSL pixel shader on specified clip. You can either run a compiled .cso file or compile a .hlsl file. Arguments: -input: The first input clip. +Input: The first input clip. -path: The path to the HLSL pixel shader file to run. +Path: The path to the HLSL pixel shader file to run. -entryPoint: If compiling HLSL source code, specified the code entry point. +EntryPoint: If compiling HLSL source code, specified the code entry point. -shaderModel: If compiling HLSL source code, specified the shader model. Usually PS_2_0 or PS_3_0 +ShaderModel: If compiling HLSL source code, specified the shader model. Usually PS_2_0 or PS_3_0 -param0-param8: Sets each of the shader parameters. +Param0-Param8: Sets each of the shader parameters. Ex: "float4 p4 : register(c4);" will be set with Param4="1,1,1,1f" End each value with 'f'(float), 'i'(int) or 'b'(bool) to specify its type. Param0 corresponds to c0, Param1 corresponds to c1, etc. If setting float or int, you can set a vector or 2, 3 or 4 elements by separating the values with ','. -clip1-clip9: The index of the clips to set into this shader. Input clips are defined when calling ExecuteShader. Clip1 sets 's0' within the shader, while clip2-clip9 set 's1' to 's8'. The order is important. +Clip1-Clip9: The index of the clips to set into this shader. Input clips are defined when calling ExecuteShader. Clip1 sets 's0' within the shader, while clip2-clip9 set 's1' to 's8'. The order is important. Default for clip1 is 1, for clip2-clip9 is 0 which means no source clip. -output: The clip index where to write the output of this shader, between 1 and 9. Default is 1 which means it will be the output of ExecuteShader. If set to another value, you can use it as the input of another shader. The last shader in the chain must have output=1. +Output: The clip index where to write the output of this shader, between 1 and 9. Default is 1 which means it will be the output of ExecuteShader. If set to another value, you can use it as the input of another shader. The last shader in the chain must have output=1. -width, height: The size of the output texture. Default = same as input texture. +Width, Height: The size of the output texture. Default = same as input texture. -#### ShaderExecute(cmd, clip1-clip9, precision) +#### ExecuteShader(cmd, Clip1-Clip9, Precision) Executes the chain of commands on specified input clips. @@ -78,16 +74,16 @@ Arguments: cmd: A clip containing the commands returned by calling Shader. -clip1-clip9: The clips on which to run the shaders. +Clip1-Clip9: The clips on which to run the shaders. -precision: 1 to execute with 8-bit precision, 2 to execute with 16-bit precision, 3 to execute with half-float precision +Precision: 1 to execute with 8-bit precision, 2 to execute with 16-bit precision, 3 to execute with half-float precision. Default=2 -precisionIn: 1 if input clips are BYTE, 2 if input clips are UINT16, 3 if input clips are half-float. Default=2 +PrecisionIn: 1 if input clips are BYTE, 2 if input clips are UINT16, 3 if input clips are half-float. Default=1 -precisionOut: 1 to get an output clip with BYTE, 2 for UINT16, 3 for half-float. Default=2 +PrecisionOut: 1 to get an output clip with BYTE, 2 for UINT16, 3 for half-float. Default=1 -#### SuperRes(input, passes, strength, softness, upscalecommand, srcMatrix601, convert) +#### SuperRes(Input, Passes, Strength, Softness, Upscalecommand, SrcMatrix601, PrecisionIn) In Shaders\SuperRes\SuperRes.avsi. Thanks to Shiandow for writing this great code! @@ -97,20 +93,20 @@ Supported video formats: YV12, YV24, RGB24 and RGB32. Arguments: -passes: How many SuperRes passes to run. Default=1. +Passes: How many SuperRes passes to run. Default=1. -strength: How agressively we want to run SuperRes, between 0 and 1. Default=1. +Strength: How agressively we want to run SuperRes, between 0 and 1. Default=1. -softness: How much smoothness we want to add, between 0 and 1. Default=0. +Softness: How much smoothness we want to add, between 0 and 1. Default=0. -upscalecommand: An upscaling command that must contain offset-correction. Ex: """nnedi3_rpow2(2, cshift="Spline16Resize")""" +Upscalecommand: An upscaling command that must contain offset-correction. Ex: """nnedi3_rpow2(2, cshift="Spline16Resize")""" -srcMatrix601: If true, the color matrix will be changed from Rec.601 to Rec.709 while running SuperRes. This avoids having to apply ColorMatrix separately. Default=false. +SrcMatrix601: If true, the color matrix will be changed from Rec.601 to Rec.709 while running SuperRes. This avoids having to apply ColorMatrix separately. Default=false. -convert: Whether to call ConvertToFloat and ConvertFromFloat() within the shader. Set to false if input is already converted. Default=true. +PrecisionIn: 0 to call ConvertToShader and ConvertFromShader within the shader. 1-3 if the source is already converted. Default=0. -#### Super-xBR(input, edgeStrength, weight, thirdPass, convert) +#### Super-xBR(Input, EdgeStrength, Sharpness, ThirdPass, Convert) In Shaders\Super-xBR\super-xbr.avsi. Thanks to Shiandow for writing this great code! @@ -120,18 +116,18 @@ Supported video formats: YV12, YV24, RGB24 and RGB32. Arguments: -edgeStrength: Value between 0 and 5 specifying the strength. Default=1. +EdgeStrength: Value between 0 and 5 specifying the strength. Default=1. -weight: Value between 0 and 1.5 specifying the weight. Default=1. +Sharpness: Value between 0 and 1.5 specifying the weight. Default=1. -thirdPass: Whether to run a 3rd pass. Default=true. +ThirdPass: Whether to run a 3rd pass. Default=true. -convert: Whether to call ConvertToFloat and ConvertFromFloat() within the shader. Set to false if input is already converted. Default=true. +PrecisionIn: 0 to call ConvertToShader and ConvertFromShader within the shader. 1-3 if the source is already converted. Default=0. #### ColorMatrix601to709(input) -In Shaders\ColorMatrix\ColorMatrix.avsi. Thanks to Shiandow for writing this great code! +In Shaders\ColorMatrix\ColorMatrix.avsi Converts color matrix from Rec.601 to Rec.709 with 16 bit depth to avoid banding. Source can be YV12, YV24, RGB24 or RGB32. diff --git a/Release/ChangeLog.txt b/Release/ChangeLog.txt index 6305d57..79972b7 100644 --- a/Release/ChangeLog.txt +++ b/Release/ChangeLog.txt @@ -1,11 +1,17 @@ Version 1.3: December 1st 2015 - SuperRes distortion problems fixed. Colors should now be accurate. - Shaders now use PrecisionIn=1 and convert frames to 16-bit on the GPU +- 10% performance increase and lowered memory usage - Fixed SuperRes when using Softness parameter -- Shader.dll now treats overflow coordinates with CLAMP +- Overflow coordinates now use 'clamp' - Fixed distortion line at the right and bottom of Super-xBR - Fixed sub-pixel shift with Super-xBR when ThirdPass=false -- 10% performance increase and lowered memory usage +- Super-xBR 'weight' argument renamed to 'sharpness' +- ConvertToFloat renamed to ConvertToShader, ConvertFromFloat renamed to ConvertFromShader +- ConvertToShader/ConvertFromShader, removed convertYuv argument +- ConvertToShader/ConvertFromShader, precision default is now 1 +- All arguments now start with a uppercase letter +- Added PrecisionIn argument to SuperRes and Super-xBR. Set to 0 to call ConvertToShader within the shader; set to 1-3 if it is already converted. Version 1.2.2: November 29th 2015 - For SuperRes, HLSL Bicubic downscaler is broken and has been disabled. Downscaling is now done in AviSynth diff --git a/Release/ReadMe.txt b/Release/ReadMe.txt index 82056e5..4cfdada 100644 --- a/Release/ReadMe.txt +++ b/Release/ReadMe.txt @@ -1,9 +1,19 @@ AviSynthShader by Etienne Charland Provides a bridge between AviSynth and HLSL pixel shaders for high bit depth processing on the GPU. +Ex: NNEDI3+SuperRes +SuperRes(2, .42, 0, """nnedi3_rpow2(2, nns=4, cshift="Spline16Resize", threads=2)""") +Ex: Super-xBR+SuperRes +ConvertToShader(Precision=2) +SuperRes(2, 1, 0, """SuperXBR(PrecisionIn=2)""", PrecisionIn=2) +ConvertFromShader("YV12", Precision=2) -SuperRes(input, passes, strength, softness, upscalecommand, srcMatrix601, convert) + + +SuperRes(Input, Passes, Strength, Softness, Upscalecommand, SrcMatrix601, PrecisionIn) + +In Shaders\SuperRes\SuperRes.avsi. Thanks to Shiandow for writing this great code! Enhances upscaling quality. @@ -11,23 +21,24 @@ Supported video formats: YV12, YV24, RGB24 and RGB32. Arguments: -passes: How many SuperRes passes to run. Default=1. +Passes: How many SuperRes passes to run. Default=1. -strength: How agressively we want to run SuperRes, between 0 and 1. Default=1. +Strength: How agressively we want to run SuperRes, between 0 and 1. Default=1. -softness: How much smoothness we want to add, between 0 and 1. Default=0. +Softness: How much smoothness we want to add, between 0 and 1. Default=0. -upscalecommand: An upscaling command that must contain offset-correction. Ex: """nnedi3_rpow2(2, cshift="Spline16Resize")""" +Upscalecommand: An upscaling command that must contain offset-correction. Ex: """nnedi3_rpow2(2, cshift="Spline16Resize")""" -srcMatrix601: If true, the color matrix will be changed from Rec.601 to Rec.709 while running SuperRes. This avoids having to apply ColorMatrix separately. Default=false. +SrcMatrix601: If true, the color matrix will be changed from Rec.601 to Rec.709 while running SuperRes. This avoids having to apply ColorMatrix separately. Default=false. -convert: Whether to call ConvertToFloat and ConvertFromFloat() within the shader. Set to false if input is already converted. Default=true. +PrecisionIn: 0 to call ConvertToShader and ConvertFromShader within the shader. 1-3 if the source is already converted. Default=0. +Super-xBR(Input, EdgeStrength, Sharpness, ThirdPass, Convert) -Super-xBR(input, edgeStrength, weight, thirdPass, convert) +In Shaders\Super-xBR\super-xbr.avsi. Thanks to Shiandow for writing this great code! Doubles the size of the image. Produces a sharp result, but with severe ringing. @@ -35,19 +46,21 @@ Supported video formats: YV12, YV24, RGB24 and RGB32. Arguments: -edgeStrength: Value between 0 and 5 specifying the strength. Default=1. +EdgeStrength: Value between 0 and 5 specifying the strength. Default=1. -weight: Value between 0 and 1.5 specifying the weight. Default=1. +Sharpness: Value between 0 and 1.5 specifying the weight. Default=1. -thirdPass: Whether to run a 3rd pass. Default=true. +ThirdPass: Whether to run a 3rd pass. Default=true. -convert: Whether to call ConvertToFloat and ConvertFromFloat() within the shader. Set to false if input is already converted. Default=true. +PrecisionIn: 0 to call ConvertToShader and ConvertFromShader within the shader. 1-3 if the source is already converted. Default=0. ColorMatrix601to709(input) +In Shaders\ColorMatrix\ColorMatrix.avsi + Converts color matrix from Rec.601 to Rec.709 with 16 bit depth to avoid banding. Source can be YV12, YV24, RGB24 or RGB32. @@ -60,7 +73,6 @@ Converts color matrix from Rec.709 to Rec.601 with 16 bit depth to avoid banding - Shaders are written by Shiandow and are available here https://github.com/zachsaw/MPDN_Extensions/ diff --git a/Release/Shader.dll b/Release/Shader.dll index 6c597df..7683eff 100644 Binary files a/Release/Shader.dll and b/Release/Shader.dll differ diff --git a/Shaders/ColorMatrix/ColorMatrix.avsi b/Shaders/ColorMatrix/ColorMatrix.avsi index 3277555..1756a8b 100644 --- a/Shaders/ColorMatrix/ColorMatrix.avsi +++ b/Shaders/ColorMatrix/ColorMatrix.avsi @@ -6,11 +6,11 @@ function ColorMatrix601to709(clip input) sourceFormat = IsYV12 ? "YV12" : IsYV24 ? "YV24" : IsRGB24 ? "RGB24" : IsRGB32 ? "RGB32" : "" Assert(sourceFormat != "", chr(10) + "Source must be YV12, YV24, RGB24 or RGB32" + chr(10)) - input = ConvertToFloat(precision=1) + input = ConvertToShader(precision=1) Shader(srcYuv ? "Yuv601ToGamma.cso" : "GammaToYuv601.cso") Shader(srcYuv ? "GammaToYuv.cso" : "YuvToGamma.cso") ExecuteShader(last, input, precision=2, precisionIn=1, precisionOut=1) - ConvertFromFloat(format=sourceFormat, precision=1) + ConvertFromShader(format=sourceFormat, precision=1) } function ColorMatrix709to601(clip input) @@ -20,9 +20,9 @@ function ColorMatrix709to601(clip input) sourceFormat = IsYV12 ? "YV12" : IsYV24 ? "YV24" : IsRGB24 ? "RGB24" : IsRGB32 ? "RGB32" : "" Assert(sourceFormat != "", chr(10) + "Source must be YV12, YV24, RGB24 or RGB32" + chr(10)) - input = ConvertToFloat(precision=1) + input = ConvertToShader(precision=1) Shader(srcYuv ? "YuvToGamma.cso" : "GammaToYuv.cso") Shader(srcYuv ? "GammaToYuv601.cso" : "Yuv601ToGamma.cso") ExecuteShader(last, input, precision=2, precisionIn=1, precisionOut=1) - ConvertFromFloat(format=sourceFormat, precision=1) + ConvertFromShader(format=sourceFormat, precision=1) } \ No newline at end of file diff --git a/Shaders/Super-xBR/super-xbr.avsi b/Shaders/Super-xBR/super-xbr.avsi index df9d996..ca41a5e 100644 --- a/Shaders/Super-xBR/super-xbr.avsi +++ b/Shaders/Super-xBR/super-xbr.avsi @@ -1,48 +1,50 @@ -function SuperXBR(clip input, float "edgeStrength", float "sharpness", bool "thirdPass", bool "convert") +function SuperXBR(clip Input, float "EdgeStrength", float "Sharpness", bool "ThirdPass", int "PrecisionIn") { - edgeStrength = default(edgeStrength, 1) - sharpness = default(sharpness, 1) - thirdPass = default(thirdPass, true) - convert = default(convert, true) - - Assert(edgeStrength >= 0 && edgeStrength <= 5, "EdgeStrength must be between 0 and 5") - Assert(sharpness >= 0 && sharpness <= 1.5, "Sharpness must be between 0 and 1.5") - Assert(convert || thirdPass, "ThirdPass is required when Convert=false") + EdgeStrength = default(EdgeStrength, 1) + Sharpness = default(Sharpness, 1) + ThirdPass = default(ThirdPass, true) + PrecisionIn = default(PrecisionIn, 0) + convert = PrecisionIn==0 + + Assert(EdgeStrength >= 0 && EdgeStrength <= 5, "EdgeStrength must be between 0 and 5") + Assert(Sharpness >= 0 && Sharpness <= 1.5, "Sharpness must be between 0 and 1.5") + Assert(convert || ThirdPass, "ThirdPass is required when PrecisionIn > 0") + Assert(PrecisionIn >= 0 && PrecisionIn <= 3, "PrecisionIn must be between 0 and 3") - input + Input - convertYuv = convert && !IsRGB() + #convertYuv = convert && !IsRGB() sourceFormat = IsYV12() ? "YV12" : IsYV24() ? "YV24" : IsRGB24() ? "RGB24" : "RGB32" - input = convert ? ConvertToFloat(precision=1) : last + Input = convert ? ConvertToShader(Precision=2) : last - input - inputWidth = convert ? width : width / 2 - inputHeight = height - args_string = string(edgeStrength,"%.32f") + "," + string(sharpness,"%.32f") + "0,0f" - size0_string = string(inputWidth) + "," + string(inputHeight)+"," + string(1./InputWidth,"%.32f") + "," + string(1./height,"%.32f")+"f" - size1_string = string(2*inputWidth) + "," + string(2*inputHeight) + "," + string(1./(2*inputWidth),"%.32f") + "," + string(1./(2*inputHeight),"%.32f")+"f" + Input + InputWidth = Width / (PrecisionIn==0 || PrecisionIn==1 ? 2 : 2) + InputHeight = Height + args_string = string(EdgeStrength,"%.32f") + "," + string(Sharpness,"%.32f") + ",0,0f" + size0_string = string(InputWidth) + "," + string(InputHeight) + "," + string(1./InputWidth,"%.32f") + "," + string(1./InputHeight,"%.32f") + "f" + size1_string = string(2*InputWidth) + "," + string(2*InputHeight) + "," + string(1./(2*InputWidth),"%.32f") + "," + string(1./(2*InputHeight),"%.32f") + "f" # It works just as well in YUV colorspace #convertYuv ? Shader("YuvToGamma.cso") : nop Shader("super-xbr-pass0.cso",\ - param2=args_string,\ - param3=size0_string,\ - width=2*inputWidth,height=2*inputHeight) + Param2 = args_string,\ + Param3 = size0_string,\ + Width = 2*InputWidth, Height = 2*InputHeight) Shader("super-xbr-pass1.cso",\ - param2=args_string,\ - param3=size1_string) + Param2=args_string,\ + Param3=size1_string) - thirdPass ? Shader("super-xbr-pass2.cso",\ - param2=args_string,\ - param3=size1_string) : nop + ThirdPass ? Shader("super-xbr-pass2.cso",\ + Param2=args_string,\ + Param3=size1_string) : nop #convertYuv ? Shader("GammaToYuv.cso") : nop - last.ExecuteShader(input, precision=2, precisionIn=convert?1:2, precisionOut=convert?1:2) + last.ExecuteShader(Input, Precision=2, PrecisionIn=convert?1:PrecisionIn, PrecisionOut=convert?1:PrecisionIn) - convert ? ConvertFromFloat(format=sourceFormat, precision=1) : last + convert ? ConvertFromShader(Format=sourceFormat, Precision=1) : last - !thirdPass ? spline36resize(width, height, -.5, -.5, width, height) : last + !ThirdPass ? spline36resize(2*InputWidth, 2*InputHeight, -.5, -.5, 2*InputWidth, 2*InputHeight) : last } \ No newline at end of file diff --git a/Shaders/SuperRes/SuperRes.avsi b/Shaders/SuperRes/SuperRes.avsi index 8172790..d69e15d 100644 --- a/Shaders/SuperRes/SuperRes.avsi +++ b/Shaders/SuperRes/SuperRes.avsi @@ -1,48 +1,53 @@ -function SuperRes(clip input, int "passes", float "strength", float "softness", string "upscalecommand", bool "srcMatrix601", bool "convert") +function SuperRes(clip Input, int "Passes", float "Strength", float "Softness", string "UpscaleCommand", bool "SrcMatrix601", int "PrecisionIn") { - passes = default(passes, 1) - strength = default(strength, 1) - softness = default(softness, 0) - convert = default(convert, true) - srcMatrix601 = default(srcMatrix601, false) - - Assert((passes > 0 && passes <= 3) ? true : false, "Passes must be between 1 and 3") - Assert((strength >= 0 && strength <= 1) ? true : false, "Strength must be between 0 and 1") - Assert((softness >= 0 && softness <= 1) ? true : false, "Softness must be between 0 and 1") - Assert(Defined(upscalecommand), "You must specify upscalecommand") - - input - - convertYuv = convert && !IsRGB() + Passes = default(Passes, 1) + Strength = default(Strength, 1) + Softness = default(Softness, 0) + SrcMatrix601 = default(SrcMatrix601, false) + PrecisionIn = default(PrecisionIn, 0) + convert = PrecisionIn==0 + + Assert((Passes > 0 && Passes <= 3) ? true : false, "Passes must be between 1 and 3") + Assert((Strength >= 0 && Strength <= 1) ? true : false, "Strength must be between 0 and 1") + Assert((Softness >= 0 && Softness <= 1) ? true : false, "Softness must be between 0 and 1") + Assert(Defined(UpscaleCommand), "You must specify UpscaleCommand") + Assert(PrecisionIn >= 0 && PrecisionIn <= 3, "PrecisionIn must be between 0 and 3") + + Input + + ConvertYuv = convert && !IsRGB() sourceFormat = IsYV12 ? "YV12" : IsYV24 ? "YV24" : IsRGB24 ? "RGB24" : IsRGB32 ? "RGB32" : "" Assert(sourceFormat != "", chr(10) + "Source must be YV12, YV24, RGB24 or RGB32" + chr(10)) - original = convert ? ConvertToFloat(precision=1) : last - Eval(upscalecommand) - input = convert ? ConvertToFloat(precision=1) : last - input.Shader(convertYuv && srcMatrix601 ? "Yuv601ToLinear.cso" : convertYuv ? "YuvToLinear.cso" : "GammaToLinear.cso") - SuperResPass(last, input, original, strength, softness, 1, passes, convertYuv, srcMatrix601) - passes > 1 ? SuperResPass(input, original, strength, softness, 2, passes, convertYuv, srcMatrix601) : nop - passes > 2 ? SuperResPass(input, original, strength, softness, 3, passes, convertYuv, srcMatrix601) : nop - !convert && srcMatrix601 ? Shader("Yuv601ToGamma.cso").Shader("GammaToYuv.cso") : last - - ExecuteShader(last, input, original, precision=3, precisionIn=convert?1:2, precisionOut=convert?1:2) - convert ? ConvertFromFloat(format=sourceFormat, precision=1) : last + Original = convert ? ConvertToShader(precision=1) : last + Eval(UpscaleCommand) + Input = convert ? ConvertToShader(precision=1) : last + Input.Shader(ConvertYuv && SrcMatrix601 ? "Yuv601ToLinear.cso" : ConvertYuv ? "YuvToLinear.cso" : "GammaToLinear.cso") + SuperResPass(last, Input, Original, Strength, Softness, 1, Passes, ConvertYuv, SrcMatrix601, PrecisionIn) + Passes > 1 ? SuperResPass(Input, Original, Strength, Softness, 2, Passes, ConvertYuv, SrcMatrix601, PrecisionIn) : nop + Passes > 2 ? SuperResPass(Input, Original, Strength, Softness, 3, Passes, ConvertYuv, SrcMatrix601, PrecisionIn) : nop + !convert && SrcMatrix601 ? Shader("Yuv601ToGamma.cso").Shader("GammaToYuv.cso") : last + + ExecuteShader(last, Input, Original, precision=3, PrecisionIn=convert?1:PrecisionIn, precisionOut=convert?1:PrecisionIn) + convert ? ConvertFromShader(format=sourceFormat, precision=1) : last } -function SuperResPass(clip cmd, clip input, clip original, float strength, float softness, int pass, int passes, bool convertYuv, bool srcMatrix601) +function SuperResPass(clip cmd, clip Input, clip Original, float Strength, float Softness, int Pass, int Passes, bool ConvertYuv, bool SrcMatrix601, int PrecisionIn) { - cmd.Shader("Bicubic.cso", output=3, \ - param0=string(original.Width) + "," + string(original.Height) + "," + string(1./original.Width,"%.32f") + "," + string(1./original.Height,"%.32f") + "f",\ - param1=string(input.Width) + "," + string(input.Height) + "," + string(1./input.Width,"%.32f") + "," + string(1./input.Height,"%.32f") + "f",\ - param2=string(1/3.,"%.32f") + "," + string(1/3.,"%.32f") + "f",\ - width=original.Width, height=original.Height) - - Shader(convertYuv && srcMatrix601 ? "SuperResDiff601.cso" : convertYuv ? "SuperResDiff709.cso" : "SuperResDiff.cso", clip1=3, clip2=2, output=4) - - Shader(pass==passes ? (convertYuv ? "SuperResFinal709.cso" : "SuperResFinal.cso") : "SuperRes.cso", clip1=1, clip2=4, output=1, \ - param0=string(input.Width) + "," + string(input.Height) + "f", \ - param1=string(1./input.Width, "%.32f") + "," + string(1./input.Height, "%.32f") + "f", \ - param2=string(original.Width) + "," + string(original.Height) + "," + string(1./(original.Width),"%.32f") + "," + string(1./original.Height,"%.32f") + "f", \ - Param3=string(strength,"%.32f") + "," + string(softness,"%.32f") + "," + string(pass) + "," + string(passes) + "f") + InputWidth = Input.Width / ((PrecisionIn==0 || PrecisionIn==1) ? 1 : 2) + OriginalWidth = Original.Width / ((PrecisionIn==0 || PrecisionIn==1) ? 1 : 2) + + cmd.Shader("Bicubic.cso", Output=3, \ + Param0=string(OriginalWidth) + "," + string(Original.Height) + "," + string(1./OriginalWidth,"%.32f") + "," + string(1./Original.Height,"%.32f") + "f",\ + Param1=string(InputWidth) + "," + string(Input.Height) + "," + string(1./InputWidth,"%.32f") + "," + string(1./Input.Height,"%.32f") + "f",\ + Param2=string(1/3.,"%.32f") + "," + string(1/3.,"%.32f") + "f",\ + Width=OriginalWidth, Height=Original.Height) + + Shader(ConvertYuv && SrcMatrix601 ? "SuperResDiff601.cso" : ConvertYuv ? "SuperResDiff709.cso" : "SuperResDiff.cso", Clip1=3, Clip2=2, Output=4) + + Shader(Pass==Passes ? (ConvertYuv ? "SuperResFinal709.cso" : "SuperResFinal.cso") : "SuperRes.cso", Clip1=1, Clip2=4, Output=1, \ + Param0=string(InputWidth) + "," + string(Input.Height) + "f", \ + Param1=string(1./InputWidth, "%.32f") + "," + string(1./Input.Height, "%.32f") + "f", \ + Param2=string(OriginalWidth) + "," + string(Original.Height) + "," + string(1./(OriginalWidth),"%.32f") + "," + string(1./Original.Height,"%.32f") + "f", \ + Param3=string(Strength,"%.32f") + "," + string(Softness,"%.32f") + "," + string(Pass) + "," + string(Passes) + "f") } \ No newline at end of file diff --git a/Src/AviSynthShader.vcxproj b/Src/AviSynthShader.vcxproj index f7cdc18..09817d8 100644 --- a/Src/AviSynthShader.vcxproj +++ b/Src/AviSynthShader.vcxproj @@ -102,16 +102,16 @@ - - + + - - + + diff --git a/Src/AviSynthShader.vcxproj.filters b/Src/AviSynthShader.vcxproj.filters index fd7ffba..049e90f 100644 --- a/Src/AviSynthShader.vcxproj.filters +++ b/Src/AviSynthShader.vcxproj.filters @@ -3,19 +3,19 @@ - - + + - - + + \ No newline at end of file diff --git a/Src/ConvertFromFloat.cpp b/Src/ConvertFromShader.cpp similarity index 82% rename from Src/ConvertFromFloat.cpp rename to Src/ConvertFromShader.cpp index 06ac196..44fe751 100644 --- a/Src/ConvertFromFloat.cpp +++ b/Src/ConvertFromShader.cpp @@ -1,13 +1,13 @@ -#include "ConvertFromFloat.h" +#include "ConvertFromShader.h" -ConvertFromFloat::ConvertFromFloat(PClip _child, const char* _format, bool _convertYuv, int _precision, IScriptEnvironment* env) : - GenericVideoFilter(_child), precision(_precision), format(_format), convertYUV(_convertYuv) { +ConvertFromShader::ConvertFromShader(PClip _child, const char* _format, int _precision, IScriptEnvironment* env) : + GenericVideoFilter(_child), precision(_precision), format(_format) { if (!vi.IsRGB32()) - env->ThrowError("ConvertFromFloat: Source must be float-precision RGB"); + env->ThrowError("ConvertFromShader: Source must be float-precision RGB"); if (strcmp(format, "YV12") != 0 && strcmp(format, "YV24") != 0 && strcmp(format, "RGB24") != 0 && strcmp(format, "RGB32") != 0) - env->ThrowError("ConvertFromFloat: Destination format must be YV12, YV24, RGB24 or RGB32"); + env->ThrowError("ConvertFromShader: Destination format must be YV12, YV24, RGB24 or RGB32"); if (precision < 1 || precision > 3) - env->ThrowError("ConvertFromFloat: Precision must be 1, 2 or 3"); + env->ThrowError("ConvertFromShader: Precision must be 1, 2 or 3"); viDst = vi; if (strcmp(format, "RGB32") == 0) @@ -35,7 +35,7 @@ ConvertFromFloat::ConvertFromFloat(PClip _child, const char* _format, bool _conv } } -ConvertFromFloat::~ConvertFromFloat() { +ConvertFromShader::~ConvertFromShader() { if (precision == 3) { free(floatBuffer); free(halfFloatBuffer); @@ -43,7 +43,7 @@ ConvertFromFloat::~ConvertFromFloat() { } -PVideoFrame __stdcall ConvertFromFloat::GetFrame(int n, IScriptEnvironment* env) { +PVideoFrame __stdcall ConvertFromShader::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); // Convert from float-precision RGB to YV24 @@ -57,7 +57,7 @@ PVideoFrame __stdcall ConvertFromFloat::GetFrame(int n, IScriptEnvironment* env) return dst; } -void ConvertFromFloat::convFloatToYV24(const byte *src, unsigned char *py, unsigned char *pu, unsigned char *pv, +void ConvertFromShader::convFloatToYV24(const byte *src, unsigned char *py, unsigned char *pu, unsigned char *pv, int pitch1, int pitch2Y, int pitch2UV, int width, int height, IScriptEnvironment* env) { const byte* srcLoop = precision == 3 ? floatBuffer : src; @@ -87,7 +87,7 @@ void ConvertFromFloat::convFloatToYV24(const byte *src, unsigned char *py, unsig } } -void ConvertFromFloat::convFloatToRGB32(const byte *src, unsigned char *dst, +void ConvertFromShader::convFloatToRGB32(const byte *src, unsigned char *dst, int pitchSrc, int pitchDst, int width, int height, IScriptEnvironment* env) { const byte* srcLoop = precision == 3 ? floatBuffer : src; @@ -119,8 +119,8 @@ void ConvertFromFloat::convFloatToRGB32(const byte *src, unsigned char *dst, } // Using Rec601 color space. Can be optimized with MMX assembly or by converting on the GPU with a shader. -// For ConvertToFloat, it's faster to process in INT, but for ConvertFromFloat, processing with FLOAT is faster -void ConvertFromFloat::convFloat(const byte* src, unsigned char* outY, unsigned char* outU, unsigned char* outV) { +// For ConvertToShader, it's faster to process in INT, but for ConvertFromShader, processing with FLOAT is faster +void ConvertFromShader::convFloat(const byte* src, unsigned char* outY, unsigned char* outU, unsigned char* outV) { float r, g, b; float y2, u2, v2; short y, u, v; @@ -184,7 +184,7 @@ void ConvertFromFloat::convFloat(const byte* src, unsigned char* outY, unsigned } // Shortcut to process BYTE or UINT16 values faster when not converting colors -void ConvertFromFloat::convInt(const byte* src, unsigned char* outY, unsigned char* outU, unsigned char* outV) { +void ConvertFromShader::convInt(const byte* src, unsigned char* outY, unsigned char* outU, unsigned char* outV) { if (precision == 1) { outV[0] = src[0]; outU[0] = src[1]; @@ -205,7 +205,7 @@ void ConvertFromFloat::convInt(const byte* src, unsigned char* outY, unsigned ch } } -uint16_t ConvertFromFloat::sadd16(uint16_t a, uint16_t b) +uint16_t ConvertFromShader::sadd16(uint16_t a, uint16_t b) { return (a > 0xFFFF - b) ? 0xFFFF : a + b; } \ No newline at end of file diff --git a/Src/ConvertFromFloat.h b/Src/ConvertFromShader.h similarity index 84% rename from Src/ConvertFromFloat.h rename to Src/ConvertFromShader.h index 6b30ae2..513ceec 100644 --- a/Src/ConvertFromFloat.h +++ b/Src/ConvertFromShader.h @@ -7,16 +7,16 @@ #include "d3dx9.h" // Converts float-precision RGB data (12-byte per pixel) into YV12 format. -class ConvertFromFloat : public GenericVideoFilter { +class ConvertFromShader : public GenericVideoFilter { public: - ConvertFromFloat(PClip _child, const char* _format, bool _convertYuv, int _precision, IScriptEnvironment* env); - ~ConvertFromFloat(); + ConvertFromShader(PClip _child, const char* _format, int _precision, IScriptEnvironment* env); + ~ConvertFromShader(); PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env); const VideoInfo& __stdcall GetVideoInfo() { return viDst; } private: const int precision; int precisionShift; - const bool convertYUV; + const bool convertYUV = false; unsigned char* floatBuffer; int floatBufferPitch; unsigned char* halfFloatBuffer; diff --git a/Src/ConvertToFloat.cpp b/Src/ConvertToShader.cpp similarity index 85% rename from Src/ConvertToFloat.cpp rename to Src/ConvertToShader.cpp index fe2946a..0e7a2b0 100644 --- a/Src/ConvertToFloat.cpp +++ b/Src/ConvertToShader.cpp @@ -1,11 +1,11 @@ -#include "ConvertToFloat.h" +#include "ConvertToShader.h" -ConvertToFloat::ConvertToFloat(PClip _child, bool _convertYuv, int _precision, IScriptEnvironment* env) : - GenericVideoFilter(_child), precision(_precision), convertYUV(_convertYuv) { +ConvertToShader::ConvertToShader(PClip _child, int _precision, IScriptEnvironment* env) : + GenericVideoFilter(_child), precision(_precision) { if (!vi.IsYV24() && !vi.IsRGB24() && !vi.IsRGB32()) - env->ThrowError("ConvertToFloat: Source must be YV12, YV24, RGB24 or RGB32"); + env->ThrowError("ConvertToShader: Source must be YV12, YV24, RGB24 or RGB32"); if (precision < 1 && precision > 3) - env->ThrowError("ConvertToFloat: Precision must be 1, 2 or 3"); + env->ThrowError("ConvertToShader: Precision must be 1, 2 or 3"); viDst = vi; viDst.pixel_type = VideoInfo::CS_BGR32; @@ -27,14 +27,14 @@ ConvertToFloat::ConvertToFloat(PClip _child, bool _convertYuv, int _precision, I } } -ConvertToFloat::~ConvertToFloat() { +ConvertToShader::~ConvertToShader() { if (precision == 3) { free(floatBuffer); free(halfFloatBuffer); } } -PVideoFrame __stdcall ConvertToFloat::GetFrame(int n, IScriptEnvironment* env) { +PVideoFrame __stdcall ConvertToShader::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); // Convert from YV24 to half-float RGB @@ -49,7 +49,7 @@ PVideoFrame __stdcall ConvertToFloat::GetFrame(int n, IScriptEnvironment* env) { return dst; } -void ConvertToFloat::convYV24ToFloat(const byte *py, const byte *pu, const byte *pv, +void ConvertToShader::convYV24ToFloat(const byte *py, const byte *pu, const byte *pv, unsigned char *dst, int pitch1Y, int pitch1UV, int pitch2, int width, int height, IScriptEnvironment* env) { unsigned char* dstLoop = precision == 3 ? floatBuffer : dst; @@ -84,7 +84,7 @@ void ConvertToFloat::convYV24ToFloat(const byte *py, const byte *pu, const byte } } -void ConvertToFloat::convRgbToFloat(const byte *src, unsigned char *dst, int srcPitch, int dstPitch, int width, int height, IScriptEnvironment* env) { +void ConvertToShader::convRgbToFloat(const byte *src, unsigned char *dst, int srcPitch, int dstPitch, int width, int height, IScriptEnvironment* env) { unsigned char* dstLoop = precision == 3 ? floatBuffer : dst; int dstLoopPitch = precision == 3 ? floatBufferPitch : dstPitch; @@ -118,7 +118,7 @@ void ConvertToFloat::convRgbToFloat(const byte *src, unsigned char *dst, int src } // Using Rec601 color space. Can be optimized with MMX assembly or by converting on the GPU with a shader. -void ConvertToFloat::convFloat(unsigned char y, unsigned char u, unsigned char v, unsigned char* out) { +void ConvertToShader::convFloat(unsigned char y, unsigned char u, unsigned char v, unsigned char* out) { int r, g, b; if (convertYUV) { b = 1164 * (y - 16) + 2018 * (u - 128); @@ -197,7 +197,7 @@ void ConvertToFloat::convFloat(unsigned char y, unsigned char u, unsigned char v } // Shortcut to process BYTE or UINT16 values faster when not converting colors -void ConvertToFloat::convInt(unsigned char y, unsigned char u, unsigned char v, unsigned char* out) { +void ConvertToShader::convInt(unsigned char y, unsigned char u, unsigned char v, unsigned char* out) { if (precision == 1) { out[0] = v; out[1] = u; @@ -212,7 +212,7 @@ void ConvertToFloat::convInt(unsigned char y, unsigned char u, unsigned char v, } // restrictions: src_stride MUST BE a multiple of 8, dst_stride MUST BE a multiple of 64 and 8x src_stride (x4 planes, x2 pixel size) -void ConvertToFloat::bitblt_i8_to_i16_sse2(const uint8_t* srcY, const uint8_t* srcU, const uint8_t* srcV, int srcPitch, uint16_t* dst, int dstPitch, int height) +void ConvertToShader::bitblt_i8_to_i16_sse2(const uint8_t* srcY, const uint8_t* srcU, const uint8_t* srcV, int srcPitch, uint16_t* dst, int dstPitch, int height) { assert(srcPitch % 2 == 0); assert(dstPitch % 16 == 0); @@ -250,7 +250,7 @@ void ConvertToFloat::bitblt_i8_to_i16_sse2(const uint8_t* srcY, const uint8_t* s } } -__m128i ConvertToFloat::load_8_16l(const void *lsb_ptr, __m128i zero) +__m128i ConvertToShader::load_8_16l(const void *lsb_ptr, __m128i zero) { assert(lsb_ptr != 0); @@ -262,7 +262,7 @@ __m128i ConvertToFloat::load_8_16l(const void *lsb_ptr, __m128i zero) return (val); } -void ConvertToFloat::store_8_16l(void *lsb_ptr, __m128i val, __m128i mask_lsb) +void ConvertToShader::store_8_16l(void *lsb_ptr, __m128i val, __m128i mask_lsb) { assert(lsb_ptr != 0); diff --git a/Src/ConvertToFloat.h b/Src/ConvertToShader.h similarity index 79% rename from Src/ConvertToFloat.h rename to Src/ConvertToShader.h index f7a8617..888525d 100644 --- a/Src/ConvertToFloat.h +++ b/Src/ConvertToShader.h @@ -7,16 +7,16 @@ #include "d3dx9.h" // Converts YV12 data into RGB data with float precision, 12-byte per pixel. -class ConvertToFloat : public GenericVideoFilter { +class ConvertToShader : public GenericVideoFilter { public: - ConvertToFloat(PClip _child, bool _convertYuv, int _precision, IScriptEnvironment* env); - ~ConvertToFloat(); + ConvertToShader(PClip _child, int _precision, IScriptEnvironment* env); + ~ConvertToShader(); PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env); const VideoInfo& __stdcall GetVideoInfo() { return viDst; } private: const int precision; int precisionShift; - const bool convertYUV; + const bool convertYUV = false; const float AlphaFloat = 1; const unsigned short AlphaShort = 0; // UINT16_MAX; unsigned char* floatBuffer; @@ -28,7 +28,7 @@ class ConvertToFloat : public GenericVideoFilter { void convRgbToFloat(const byte *src, unsigned char *dst, int srcPitch, int dstPitch, int width, int height, IScriptEnvironment* env); void convFloat(unsigned char y, unsigned char u, unsigned char v, unsigned char *out); void convInt(byte y, unsigned char u, unsigned char v, unsigned char* out); - void ConvertToFloat::bitblt_i8_to_i16_sse2(const uint8_t* srcY, const uint8_t* srcU, const uint8_t* srcV, int srcPitch, uint16_t* dst, int dstPitch, int height); + void ConvertToShader::bitblt_i8_to_i16_sse2(const uint8_t* srcY, const uint8_t* srcU, const uint8_t* srcV, int srcPitch, uint16_t* dst, int dstPitch, int height); __m128i load_8_16l(const void *lsb_ptr, __m128i zero); void store_8_16l(void *lsb_ptr, __m128i val, __m128i mask_lsb); VideoInfo viDst; diff --git a/Src/ExecuteShader.cpp b/Src/ExecuteShader.cpp index a50b7b5..f180b66 100644 --- a/Src/ExecuteShader.cpp +++ b/Src/ExecuteShader.cpp @@ -149,7 +149,7 @@ void ExecuteShader::CreateInputClip(int index, IScriptEnvironment* env) { PClip clip = m_clips[index]; if (clip != NULL) { if (!clip->GetVideoInfo().IsRGB32()) - env->ThrowError("ExecuteShader: Source must be float-precision RGB"); + env->ThrowError("ExecuteShader: You must first call ConvertToShader on source"); if (FAILED(render->CreateInputTexture(index, index + 1, clip->GetVideoInfo().width / precisionIn, clip->GetVideoInfo().height, true, false))) env->ThrowError("ExecuteShader: Failed to create input textures."); diff --git a/Src/Init.cpp b/Src/Init.cpp index 4139c53..9756d2f 100644 --- a/Src/Init.cpp +++ b/Src/Init.cpp @@ -1,41 +1,28 @@ #include #include "avisynth.h" -#include "ConvertToFloat.h" -#include "ConvertFromFloat.h" +#include "ConvertToShader.h" +#include "ConvertFromShader.h" #include "Shader.h" #include "ExecuteShader.h" -const int DefaultPrecision = 2; const int DefaultConvertYuv = false; -AVSValue __cdecl Create_ConvertToFloat(AVSValue args, void* user_data, IScriptEnvironment* env) { +AVSValue __cdecl Create_ConvertToShader(AVSValue args, void* user_data, IScriptEnvironment* env) { PClip input = args[0].AsClip(); - bool ConvertYuv = args[1].AsBool(DefaultConvertYuv); if (input->GetVideoInfo().IsYV12()) input = env->Invoke("ConvertToYV24", input).AsClip(); - // Don't convert YUV to RGB when source format is RGB32. - if (input->GetVideoInfo().IsRGB32()) - ConvertYuv = false; - return new ConvertToFloat( + return new ConvertToShader( input, // source clip - ConvertYuv, // whether to convert YUV to RGB on the CPU - args[2].AsInt(DefaultPrecision), // precision, 1 for RGB32, 2 for UINT16 and 3 for half-float data. + args[1].AsInt(1), // precision, 1 for RGB32, 2 for UINT16 and 3 for half-float data. env); // env is the link to essential informations, always provide it } -AVSValue __cdecl Create_ConvertFromFloat(AVSValue args, void* user_data, IScriptEnvironment* env) { - const char* Format = args[1].AsString("YV12"); - bool ConvertYuv = args[2].AsBool(DefaultConvertYuv); - // Don't convert RGB to YUV when destination format is RGB32. - if (strcmp(Format, "RGB32") == 0) - ConvertYuv = false; - - ConvertFromFloat* Result = new ConvertFromFloat( +AVSValue __cdecl Create_ConvertFromShader(AVSValue args, void* user_data, IScriptEnvironment* env) { + ConvertFromShader* Result = new ConvertFromShader( args[0].AsClip(), // source clip - Format, // destination format - ConvertYuv, // whether to convert RGB to YUV on the CPU - args[3].AsInt(DefaultPrecision), // precision, 1 for RGB32, 2 for UINT16 and 3 for half-float data. + args[1].AsString("YV12"), // destination format + args[2].AsInt(1), // precision, 1 for RGB32, 2 for UINT16 and 3 for half-float data. env); // env is the link to essential informations, always provide it if (strcmp(args[1].AsString("YV12"), "YV12") == 0) @@ -75,8 +62,6 @@ AVSValue __cdecl Create_Shader(AVSValue args, void* user_data, IScriptEnvironmen } AVSValue __cdecl Create_ExecuteShader(AVSValue args, void* user_data, IScriptEnvironment* env) { - int Precision = args[10].AsInt(DefaultPrecision); // precision - return new ExecuteShader( args[0].AsClip(), // source clip containing commands args[1].AsClip(), // clip 1 @@ -88,9 +73,9 @@ AVSValue __cdecl Create_ExecuteShader(AVSValue args, void* user_data, IScriptEnv args[7].AsClip(), // clip 7 args[8].AsClip(), // clip 8 args[9].AsClip(), // clip 9 - Precision, // precision - args[11].AsInt(Precision), // precisionIn - args[12].AsInt(Precision), // precisionOut + args[10].AsInt(2), // precision + args[11].AsInt(1), // precisionIn + args[12].AsInt(1), // precisionOut env); } @@ -98,9 +83,9 @@ const AVS_Linkage *AVS_linkage = 0; extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) { AVS_linkage = vectors; - env->AddFunction("ConvertToFloat", "c[convertYuv]b[precision]i", Create_ConvertToFloat, 0); - env->AddFunction("ConvertFromFloat", "c[format]s[convertYuv]b[precision]i", Create_ConvertFromFloat, 0); - env->AddFunction("Shader", "c[path]s[entryPoint]s[shaderModel]s[param0]s[param1]s[param2]s[param3]s[param4]s[param5]s[param6]s[param7]s[param8]s[clip1]i[clip2]i[clip3]i[clip4]i[clip5]i[clip6]i[clip7]i[clip8]i[clip9]i[output]i[width]i[height]i", Create_Shader, 0); - env->AddFunction("ExecuteShader", "c[clip1]c[clip2]c[clip3]c[clip4]c[clip5]c[clip6]c[clip7]c[clip8]c[clip9]c[precision]i[precisionIn]i[precisionOut]i", Create_ExecuteShader, 0); + env->AddFunction("ConvertToShader", "c[Precision]i", Create_ConvertToShader, 0); + env->AddFunction("ConvertFromShader", "c[Format]s[Precision]i", Create_ConvertFromShader, 0); + env->AddFunction("Shader", "c[Path]s[EntryPoint]s[ShaderModel]s[Param0]s[Param1]s[Param2]s[Param3]s[Param4]s[Param5]s[Param6]s[Param7]s[Param8]s[Clip1]i[Clip2]i[Clip3]i[Clip4]i[Clip5]i[Clip6]i[Clip7]i[Clip8]i[Clip9]i[Output]i[Width]i[Height]i", Create_Shader, 0); + env->AddFunction("ExecuteShader", "c[Clip1]c[Clip2]c[Clip3]c[Clip4]c[Clip5]c[Clip6]c[Clip7]c[Clip8]c[Clip9]c[Precision]i[PrecisionIn]i[PrecisionOut]i", Create_ExecuteShader, 0); return "Shader plugin"; }