DXGL r459 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r458‎ | r459 | r460 >
Date:23:50, 6 July 2014
Author:admin
Status:new
Tags:
Comment:
Add clipping support to Blt; clipper vertex calculation is currently broken.
Modified paths:
  • /ddraw/ShaderGen2D.cpp (modified) (history)
  • /ddraw/ShaderManager.cpp (modified) (history)
  • /ddraw/ShaderManager.h (modified) (history)
  • /ddraw/glDirectDrawSurface.cpp (modified) (history)
  • /ddraw/glDirectDrawSurface.h (modified) (history)
  • /ddraw/glRenderer.cpp (modified) (history)
  • /ddraw/glRenderer.h (modified) (history)
  • /ddraw/glUtil.h (modified) (history)

Diff [purge]

Index: ddraw/ShaderGen2D.cpp
@@ -155,6 +155,7 @@
156156 static const char attr_srcst[] = "attribute vec2 srcst;\n";
157157 static const char attr_destst[] = "attribute vec2 destst;\n";
158158 static const char attr_patternst[] = "attribute vec2 patternst;\n";
 159+static const char attr_stencilst[] = "attribute vec2 stencilst;\n";
159160
160161 // Uniforms
161162 static const char unif_view[] = "uniform vec4 view;\n";
@@ -161,6 +162,7 @@
162163 static const char unif_srctex[] = "uniform sampler2D srctex;\n";
163164 static const char unif_desttex[] = "uniform sampler2D desttex;\n";
164165 static const char unif_patterntex[] = "uniform sampler2D patterntex;\n";
 166+static const char unif_stenciltex[] = "uniform sampler2D stenciltex;\n";
165167 static const char unif_ckeysrc[] = "uniform ivec3 ckeysrc;\n";
166168 static const char unif_ckeydest[] = "uniform ivec3 ckeydest;\n";
167169
@@ -186,9 +188,10 @@
187189 gl_Position = proj * xyzw;\n";
188190 static const char op_vertcolorrgb[] = "gl_FrontColor = vec4(rgb,1.0);\n";
189191 static const char op_texcoord0[] = "gl_TexCoord[0] = vec4(srcst,0.0,1.0);\n";
 192+static const char op_texcoord3[] = "gl_TexCoord[3] = vec4(stencilst,0.0,1.0);\n";
190193 static const char op_ckeysrc[] = "if(pixel.rgb == ckeysrc) discard;\n";
 194+static const char op_clip[] = "if(texture2D(stenciltex, gl_TexCoord[3].st).r < .5) discard;";
191195
192 -
193196 // Functions
194197
195198 // ROP Operations
@@ -790,6 +793,7 @@
791794 String_Append(vsrc, attr_xy);
792795 if (id & DDBLT_COLORFILL) String_Append(vsrc, attr_rgb);
793796 else String_Append(vsrc, attr_srcst);
 797+ if (id & 0x10000000) String_Append(vsrc, attr_stencilst);
794798
795799 // Uniforms
796800 String_Append(vsrc, unif_view);
@@ -799,6 +803,7 @@
800804 String_Append(vsrc, op_vertex);
801805 if (id & DDBLT_COLORFILL) String_Append(vsrc, op_vertcolorrgb);
802806 else String_Append(vsrc, op_texcoord0);
 807+ if (id & 0x10000000) String_Append(vsrc, op_texcoord3);
803808 String_Append(vsrc, mainend);
804809 #ifdef _DEBUG
805810 OutputDebugStringA("2D blitter vertex shader:\n");
@@ -849,6 +854,7 @@
850855
851856 // Uniforms
852857 if (!(id & DDBLT_COLORFILL)) String_Append(fsrc, unif_srctex);
 858+ if (id & 0x10000000) String_Append(fsrc, unif_stenciltex);
853859 if (id & DDBLT_KEYSRC) String_Append(fsrc, unif_ckeysrc);
854860
855861 // Variables
@@ -856,6 +862,7 @@
857863
858864 // Main
859865 String_Append(fsrc, mainstart);
 866+ if (id & 0x10000000) String_Append(fsrc, op_clip);
860867 if (id & DDBLT_COLORFILL) String_Append(fsrc, op_color);
861868 else String_Append(fsrc, op_src);
862869 if (id & DDBLT_KEYSRC) String_Append(fsrc, op_ckeysrc);
@@ -905,10 +912,12 @@
906913 gen->genshaders2D[index].shader.attribs[3] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "srcst");
907914 gen->genshaders2D[index].shader.attribs[4] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "destst");
908915 gen->genshaders2D[index].shader.attribs[5] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "patternst");
 916+ gen->genshaders2D[index].shader.attribs[6] = gen->ext->glGetAttribLocation(gen->genshaders2D[index].shader.prog, "stencilst");
909917 gen->genshaders2D[index].shader.uniforms[0] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "view");
910918 gen->genshaders2D[index].shader.uniforms[1] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "srctex");
911919 gen->genshaders2D[index].shader.uniforms[2] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "desttex");
912920 gen->genshaders2D[index].shader.uniforms[3] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "patterntex");
913 - gen->genshaders2D[index].shader.uniforms[4] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "ckeysrc");
914 - gen->genshaders2D[index].shader.uniforms[5] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "ckeydest");
 921+ gen->genshaders2D[index].shader.uniforms[4] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "stenciltex");
 922+ gen->genshaders2D[index].shader.uniforms[5] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "ckeysrc");
 923+ gen->genshaders2D[index].shader.uniforms[6] = gen->ext->glGetUniformLocation(gen->genshaders2D[index].shader.prog, "ckeydest");
915924 }
\ No newline at end of file
Index: ddraw/ShaderManager.cpp
@@ -98,6 +98,13 @@
9999 gl_FragColor = value;\n\
100100 } ";
101101
 102+const char frag_clipstencil[] = "\
 103+#version 110\n\
 104+void main (void)\n\
 105+{\n\
 106+ gl_FragColor = vec4(1.0,0.0,0.0,0.0);\n\
 107+} ";
 108+
102109 const char vert_ortho[] = "\
103110 #version 110\n\
104111 uniform vec4 view;\n\
@@ -129,7 +136,8 @@
130137 {0,0, vert_ortho, frag_Pal256, 0,-1,-1,-1},
131138 {0,0, vert_ortho, frag_ColorKey, 0,-1,-1,-1},
132139 {0,0, vert_ortho, frag_ColorKeyMask, 0,-1,-1,-1},
133 - {0,0, vert_ortho, frag_2ColorKey, 0,-1,-1,-1}
 140+ {0,0, vert_ortho, frag_2ColorKey, 0,-1,-1,-1},
 141+ {0,0, vert_ortho, frag_clipstencil, 0,-1,-1,-1}
134142 };
135143 const int SHADER_END = __LINE__ - 4;
136144 const int NumberOfShaders = SHADER_END - SHADER_START;
Index: ddraw/ShaderManager.h
@@ -44,6 +44,7 @@
4545 #define PROG_CKEY 3
4646 #define PROG_CKEYMASK 4
4747 #define PROG_2CKEY 5
 48+#define PROG_CLIPSTENCIL 6
4849
4950 struct TEXTURESTAGE;
5051 class ShaderGen3D;
Index: ddraw/glDirectDrawSurface.cpp
@@ -628,6 +628,33 @@
629629 src->ddsd.ddpfPixelFormat.dwRGBBitCount);
630630 src->dirty &= ~1;
631631 }
 632+ if (clipper)
 633+ {
 634+ if (!clipper->hWnd)
 635+ {
 636+ if (!stencil)
 637+ {
 638+ stencil = (TEXTURE*)malloc(sizeof(TEXTURE));
 639+ ZeroMemory(stencil, sizeof(TEXTURE));
 640+ stencil->minfilter = stencil->magfilter = GL_NEAREST;
 641+ stencil->wraps = stencil->wrapt = GL_CLAMP_TO_EDGE;
 642+ stencil->pixelformat.dwSize = sizeof(DDPIXELFORMAT);
 643+ stencil->pixelformat.dwFlags = DDPF_RGB|DDPF_ALPHAPIXELS;
 644+ stencil->pixelformat.dwBBitMask = 0xF;
 645+ stencil->pixelformat.dwGBitMask = 0xF0;
 646+ stencil->pixelformat.dwRBitMask = 0xF00;
 647+ stencil->pixelformat.dwRGBAlphaBitMask = 0xF000;
 648+ stencil->pixelformat.dwRGBBitCount = 16;
 649+ glRenderer_MakeTexture(ddInterface->renderer, stencil, ddsd.dwWidth, ddsd.dwHeight);
 650+ }
 651+ if (clipper->dirty)
 652+ {
 653+ glRenderer_UpdateClipper(ddInterface->renderer, this);
 654+ clipper->dirty = false;
 655+ }
 656+ }
 657+ dwFlags |= 0x10000000;
 658+ }
632659 if (this == src)
633660 {
634661 tmprect.left = tmprect.top = 0;
Index: ddraw/glDirectDrawSurface.h
@@ -137,6 +137,7 @@
138138 D3DMATERIALHANDLE handle;
139139 FBO fbo;
140140 FBO stencilfbo;
 141+ glDirectDrawClipper *clipper;
141142 private:
142143 int swapinterval;
143144 ULONG refcount;
@@ -147,7 +148,6 @@
148149 glDirectDraw7 *ddInterface;
149150 int surfacetype; // 0-generic memory, 1-GDI surface, 2-OpenGL Texture
150151 glDirectDrawSurface7 *backbuffer;
151 - glDirectDrawClipper *clipper;
152152 int pagelocked;
153153 GLint magfilter,minfilter;
154154 glDirect3DDevice7 *device;
Index: ddraw/glRenderer.cpp
@@ -26,6 +26,7 @@
2727 #include "glRenderer.h"
2828 #include "glDirect3DDevice.h"
2929 #include "glDirect3DLight.h"
 30+#include "glDirectDrawClipper.h"
3031 #include "ddraw.h"
3132 #include "scalers.h"
3233 #include "ShaderGen3D.h"
@@ -629,7 +630,7 @@
630631 * @param This
631632 * Pointer to glRenderer object
632633 * @param fbo
633 - * FBO Structure containing framebuffer to delete.
 634+ * FBO Structure containing framebuffer to delete
634635 */
635636 void glRenderer_DeleteFBO(glRenderer *This, FBO *fbo)
636637 {
@@ -642,6 +643,24 @@
643644 }
644645
645646 /**
 647+ * Updates the clipper stencil for a surface.
 648+ * @param This
 649+ * Pointer to glRenderer object
 650+ * @param surface
 651+ * Surface to update clipper stencil on
 652+ */
 653+void glRenderer_UpdateClipper(glRenderer *This, glDirectDrawSurface7 *surface)
 654+{
 655+ EnterCriticalSection(&This->cs);
 656+ This->inputs[0] = surface;
 657+ This->opcode = OP_UPDATECLIPPER;
 658+ SetEvent(This->start);
 659+ WaitForSingleObject(This->busy,INFINITE);
 660+ LeaveCriticalSection(&This->cs);
 661+}
 662+
 663+
 664+/**
646665 * Gets an estimate of the scanline currently being drawn.
647666 * @param This
648667 * Pointer to glRenderer object
@@ -763,6 +782,9 @@
764783 case OP_DELETEFBO:
765784 glRenderer__DeleteFBO(This,(FBO*)This->inputs[0]);
766785 break;
 786+ case OP_UPDATECLIPPER:
 787+ glRenderer__UpdateClipper(This,(glDirectDrawSurface7*)This->inputs[0]);
 788+ break;
767789 }
768790 }
769791 return 0;
@@ -966,6 +988,13 @@
967989 This->bltvertices[0].s = This->bltvertices[2].s = (GLfloat)srcrect.right / (GLfloat)ddsdSrc.dwWidth;
968990 This->bltvertices[0].t = This->bltvertices[1].t = (GLfloat)srcrect.top / (GLfloat)ddsdSrc.dwHeight;
969991 This->bltvertices[2].t = This->bltvertices[3].t = (GLfloat)srcrect.bottom / (GLfloat)ddsdSrc.dwHeight;
 992+ if(dwFlags & 0x10000000)
 993+ {
 994+ This->blttexcoords[1].stencils = This->blttexcoords[3].stencils = This->bltvertices[1].x / (GLfloat)dest->fakex;
 995+ This->blttexcoords[0].stencils = This->blttexcoords[2].stencils = This->bltvertices[0].x / (GLfloat)dest->fakex;
 996+ This->blttexcoords[0].stencilt = This->blttexcoords[1].stencilt = This->bltvertices[0].y / (GLfloat)dest->fakey;
 997+ This->blttexcoords[2].stencilt = This->blttexcoords[3].stencilt = This->bltvertices[2].y / (GLfloat)dest->fakey;
 998+ }
970999 if(dest->zbuffer) glClear(GL_DEPTH_BUFFER_BIT);
9711000 if(dwFlags & DDBLT_COLORFILL)
9721001 {
@@ -1010,17 +1039,17 @@
10111040 switch(This->ddInterface->GetBPP())
10121041 {
10131042 case 8:
1014 - if(This->ext->glver_major >= 3) This->ext->glUniform3i(shader->shader.uniforms[4],src->colorkey[0].key.dwColorSpaceHighValue,0,0);
1015 - else This->ext->glUniform3i(shader->shader.uniforms[4],src->colorkey[0].key.dwColorSpaceHighValue,src->colorkey[0].key.dwColorSpaceHighValue,
 1043+ if(This->ext->glver_major >= 3) This->ext->glUniform3i(shader->shader.uniforms[5],src->colorkey[0].key.dwColorSpaceHighValue,0,0);
 1044+ else This->ext->glUniform3i(shader->shader.uniforms[5],src->colorkey[0].key.dwColorSpaceHighValue,src->colorkey[0].key.dwColorSpaceHighValue,
10161045 src->colorkey[0].key.dwColorSpaceHighValue);
10171046 break;
10181047 case 15:
1019 - This->ext->glUniform3i(shader->shader.uniforms[4],_5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>10 & 31),
 1048+ This->ext->glUniform3i(shader->shader.uniforms[5],_5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>10 & 31),
10201049 _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>5 & 31),
10211050 _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue & 31));
10221051 break;
10231052 case 16:
1024 - This->ext->glUniform3i(shader->shader.uniforms[4],_5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>11 & 31),
 1053+ This->ext->glUniform3i(shader->shader.uniforms[5],_5to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>11 & 31),
10251054 _6to8bit(src->colorkey[0].key.dwColorSpaceHighValue>>5 & 63),
10261055 _5to8bit(src->colorkey[0].key.dwColorSpaceHighValue & 31));
10271056 break;
@@ -1027,7 +1056,7 @@
10281057 case 24:
10291058 case 32:
10301059 default:
1031 - This->ext->glUniform3i(shader->shader.uniforms[4],(src->colorkey[0].key.dwColorSpaceHighValue>>16 & 255),
 1060+ This->ext->glUniform3i(shader->shader.uniforms[5],(src->colorkey[0].key.dwColorSpaceHighValue>>16 & 255),
10321061 (src->colorkey[0].key.dwColorSpaceHighValue>>8 & 255),
10331062 (src->colorkey[0].key.dwColorSpaceHighValue & 255));
10341063 break;
@@ -1038,6 +1067,13 @@
10391068 {
10401069 This->ext->glUniform1i(shader->shader.uniforms[1],0);
10411070 }
 1071+ if (dwFlags & 0x10000000) // Use clipper
 1072+ {
 1073+ TextureManager_SetTexture(This->texman, 3, dest->stencil);
 1074+ This->ext->glUniform1i(shader->shader.uniforms[4],3);
 1075+ This->util->EnableArray(shader->shader.attribs[6],true);
 1076+ This->ext->glVertexAttribPointer(shader->shader.attribs[6], 2, GL_FLOAT, false, sizeof(BltTexcoord), &This->blttexcoords[0].stencils);
 1077+ }
10421078 if(src)
10431079 {
10441080 TextureManager_SetTexture(This->texman,0,src->GetTexture());
@@ -1397,7 +1433,7 @@
13981434 SetEvent(This->busy);
13991435 }
14001436
1401 -void glRenderer_SetBlend(glRenderer *This, DWORD src, DWORD dest)
 1437+void glRenderer__SetBlend(glRenderer *This, DWORD src, DWORD dest)
14021438 {
14031439 GLenum glsrc, gldest;
14041440 bool bothalpha = false;
@@ -1694,7 +1730,7 @@
16951731 This->util->SetDepthRange(device->viewport.dvMinZ,device->viewport.dvMaxZ);
16961732 if(device->renderstate[D3DRENDERSTATE_ALPHABLENDENABLE]) This->util->BlendEnable(true);
16971733 else This->util->BlendEnable(false);
1698 - glRenderer_SetBlend(This,device->renderstate[D3DRENDERSTATE_SRCBLEND],device->renderstate[D3DRENDERSTATE_DESTBLEND]);
 1734+ glRenderer__SetBlend(This,device->renderstate[D3DRENDERSTATE_SRCBLEND],device->renderstate[D3DRENDERSTATE_DESTBLEND]);
16991735 This->util->SetCull((D3DCULL)device->renderstate[D3DRENDERSTATE_CULLMODE]);
17001736 glRenderer__SetFogColor(This,device->renderstate[D3DRENDERSTATE_FOGCOLOR]);
17011737 glRenderer__SetFogStart(This,*(GLfloat*)(&device->renderstate[D3DRENDERSTATE_FOGSTART]));
@@ -1718,6 +1754,46 @@
17191755 SetEvent(This->busy);
17201756 }
17211757
 1758+void glRenderer__UpdateClipper(glRenderer *This, glDirectDrawSurface7 *surface)
 1759+{
 1760+ GLfloat view[4];
 1761+ if (!surface->stencil)
 1762+ {
 1763+ surface->stencil = (TEXTURE*)malloc(sizeof(TEXTURE));
 1764+ ZeroMemory(surface->stencil, sizeof(TEXTURE));
 1765+ surface->stencil->minfilter = surface->stencil->magfilter = GL_NEAREST;
 1766+ surface->stencil->wraps = surface->stencil->wrapt = GL_CLAMP_TO_EDGE;
 1767+ surface->stencil->pixelformat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
 1768+ surface->stencil->pixelformat.dwBBitMask = 0xF;
 1769+ surface->stencil->pixelformat.dwGBitMask = 0xF0;
 1770+ surface->stencil->pixelformat.dwRBitMask = 0xF00;
 1771+ surface->stencil->pixelformat.dwZBitMask = 0xF000;
 1772+ surface->stencil->pixelformat.dwRGBBitCount = 16;
 1773+ TextureManager__CreateTexture(This->texman, surface->stencil, surface->ddsd.dwWidth, surface->ddsd.dwHeight);
 1774+ }
 1775+ if ((surface->ddsd.dwWidth != surface->stencil->width) ||
 1776+ (surface->ddsd.dwHeight != surface->stencil->height))
 1777+ TextureManager__UploadTexture(This->texman, surface->stencil, 0, NULL,
 1778+ surface->ddsd.dwWidth, surface->ddsd.dwHeight);
 1779+ This->util->SetFBO(&surface->stencilfbo, surface->stencil, 0, false);
 1780+ view[0] = view[2] = 0;
 1781+ view[1] = (GLfloat)surface->ddsd.dwWidth;
 1782+ view[3] = (GLfloat)surface->ddsd.dwHeight;
 1783+ This->util->SetViewport(0,0,surface->ddsd.dwWidth,surface->ddsd.dwHeight);
 1784+ glClear(GL_COLOR_BUFFER_BIT);
 1785+ This->shaders->SetShader(PROG_CLIPSTENCIL,NULL,NULL,0);
 1786+ This->ext->glUniform4f(This->shaders->shaders[PROG_CLIPSTENCIL].view,view[0],view[1],view[2],view[3]);
 1787+ This->util->EnableArray(This->shaders->shaders[PROG_CLIPSTENCIL].pos,true);
 1788+ This->ext->glVertexAttribPointer(This->shaders->shaders[PROG_CLIPSTENCIL].pos,
 1789+ 2,GL_FLOAT,false,sizeof(BltVertex),&surface->clipper->vertices[0].x);
 1790+ This->util->SetCull(D3DCULL_NONE);
 1791+ This->util->SetPolyMode(D3DFILL_SOLID);
 1792+ This->ext->glDrawRangeElements(GL_TRIANGLES, 0, (6 * surface->clipper->clipsize) - 1,
 1793+ 4 * surface->clipper->clipsize, GL_UNSIGNED_SHORT, surface->clipper->indices);
 1794+ This->util->SetFBO((FBO*)NULL);
 1795+ SetEvent(This->busy);
 1796+}
 1797+
17221798 void glRenderer__SetFogColor(glRenderer *This, DWORD color)
17231799 {
17241800 if (color == This->fogcolor) return;
Index: ddraw/glRenderer.h
@@ -65,6 +65,7 @@
6666 #define OP_FLUSH 11
6767 #define OP_DRAWPRIMITIVES 12
6868 #define OP_DELETEFBO 13
 69+#define OP_UPDATECLIPPER 14
6970
7071 #ifdef __cplusplus
7172 class glDirectDraw7;
@@ -111,6 +112,7 @@
112113 GLfloat fogend;
113114 GLfloat fogdensity;
114115 BltVertex bltvertices[4];
 116+ BltTexcoord blttexcoords[4];
115117 int oldswap;
116118 TextureManager *texman;
117119 glUtil *util;
@@ -134,6 +136,7 @@
135137 HRESULT glRenderer_DrawPrimitives(glRenderer *This, glDirect3DDevice7 *device, GLenum mode, GLVERTEX *vertices, int *texformats, DWORD count, LPWORD indices,
136138 DWORD indexcount, DWORD flags);
137139 void glRenderer_DeleteFBO(glRenderer *This, FBO *fbo);
 140+void glRenderer_UpdateClipper(glRenderer *This, glDirectDrawSurface7 *surface);
138141 unsigned int glRenderer_GetScanLine(glRenderer *This);
139142 // In-thread APIs
140143 DWORD glRenderer__Entry(glRenderer *This);
@@ -153,12 +156,13 @@
154157 void glRenderer__Flush(glRenderer *This);
155158 void glRenderer__SetWnd(glRenderer *This, int width, int height, int fullscreen, int bpp, unsigned int frequency, HWND newwnd);
156159 void glRenderer__DeleteFBO(glRenderer *This, FBO *fbo);
 160+void glRenderer__UpdateClipper(glRenderer *This, glDirectDrawSurface7 *surface);
157161 void glRenderer__SetFogColor(glRenderer *This, DWORD color);
158162 void glRenderer__SetFogStart(glRenderer *This, GLfloat start);
159163 void glRenderer__SetFogEnd(glRenderer *This, GLfloat end);
160164 void glRenderer__SetFogDensity(glRenderer *This, GLfloat density);
161165 inline void glRenderer__SetSwap(glRenderer *This, int swap);
162 -void glRenderer_SetBlend(glRenderer *This, DWORD src, DWORD dest);
 166+void glRenderer__SetBlend(glRenderer *This, DWORD src, DWORD dest);
163167
164168 #ifdef __cplusplus
165169 }
Index: ddraw/glUtil.h
@@ -37,6 +37,12 @@
3838 GLfloat padding;
3939 } BltVertex;
4040
 41+typedef struct
 42+{
 43+ GLfloat patterns, patternt;
 44+ GLfloat stencils, stencilt;
 45+} BltTexcoord;
 46+
4147 class glDirectDrawSurface7;
4248
4349 class glUtil