@@ -23,6 +23,10 @@ public class GlTexture {
2323 private static GlTexture boundTexture ;
2424 private static int activeTexture = 0 ;
2525
26+ private static int unpackRowLength ;
27+ private static int unpackSkipRows ;
28+ private static int unpackSkipPixels ;
29+
2630 public static void bindIdToImage (int id , VulkanImage vulkanImage ) {
2731 GlTexture texture = map .get (id );
2832 texture .vulkanImage = vulkanImage ;
@@ -79,7 +83,9 @@ public static void texImage2D(int target, int level, int internalFormat, int wid
7983 if (checkParams (level , width , height ))
8084 return ;
8185
82- boundTexture .allocateIfNeeded (width , height , internalFormat , type );
86+ boundTexture .updateParams (level , width , height , internalFormat , type );
87+ boundTexture .allocateIfNeeded ();
88+
8389 VTextureSelector .bindTexture (activeTexture , boundTexture .vulkanImage );
8490
8591 texSubImage2D (target , level , 0 , 0 , width , height , format , type , pixels );
@@ -89,7 +95,9 @@ public static void texImage2D(int target, int level, int internalFormat, int wid
8995 if (checkParams (level , width , height ))
9096 return ;
9197
92- boundTexture .allocateIfNeeded (width , height , internalFormat , type );
98+ boundTexture .updateParams (level , width , height , internalFormat , type );
99+ boundTexture .allocateIfNeeded ();
100+
93101 VTextureSelector .bindTexture (activeTexture , boundTexture .vulkanImage );
94102
95103 texSubImage2D (target , level , 0 , 0 , width , height , format , type , pixels );
@@ -99,11 +107,6 @@ private static boolean checkParams(int level, int width, int height) {
99107 if (width == 0 || height == 0 )
100108 return true ;
101109
102- // TODO: levels
103- if (level != 0 ) {
104- // throw new UnsupportedOperationException();
105- return true ;
106- }
107110 return false ;
108111 }
109112
@@ -127,7 +130,7 @@ public static void texSubImage2D(int target, int level, int xOffset, int yOffset
127130 }
128131
129132 if (src != null )
130- boundTexture .uploadSubImage (xOffset , yOffset , width , height , format , src );
133+ boundTexture .uploadSubImage (level , xOffset , yOffset , width , height , format , src );
131134 }
132135
133136 private static ByteBuffer getByteBuffer (int width , int height , long pixels ) {
@@ -157,7 +160,7 @@ public static void texSubImage2D(int target, int level, int xOffset, int yOffset
157160 }
158161
159162 if (src != null )
160- boundTexture .uploadSubImage (xOffset , yOffset , width , height , format , src );
163+ boundTexture .uploadSubImage (level , xOffset , yOffset , width , height , format , src );
161164 }
162165
163166 public static void texParameteri (int target , int pName , int param ) {
@@ -200,6 +203,14 @@ public static int getTexLevelParameter(int target, int level, int pName) {
200203 };
201204 }
202205
206+ public static void pixelStoreI (int pName , int value ) {
207+ switch (pName ) {
208+ case GL11 .GL_UNPACK_ROW_LENGTH -> unpackRowLength = value ;
209+ case GL11 .GL_UNPACK_SKIP_ROWS -> unpackSkipRows = value ;
210+ case GL11 .GL_UNPACK_SKIP_PIXELS -> unpackSkipPixels = value ;
211+ }
212+ }
213+
203214 public static void generateMipmap (int target ) {
204215 if (target != GL11 .GL_TEXTURE_2D )
205216 throw new UnsupportedOperationException ("target != GL_TEXTURE_2D not supported" );
@@ -237,7 +248,9 @@ public static GlTexture getBoundTexture() {
237248
238249 final int id ;
239250 VulkanImage vulkanImage ;
240- int internalFormat ;
251+
252+ int width , height ;
253+ int vkFormat ;
241254
242255 boolean needsUpdate = false ;
243256 int maxLevel = 0 ;
@@ -250,14 +263,27 @@ public GlTexture(int id) {
250263 this .id = id ;
251264 }
252265
253- void allocateIfNeeded ( int width , int height , int internalFormat , int type ) {
254- this .internalFormat = internalFormat ;
255- int vkFormat = GlUtil . vulkanFormat ( internalFormat , type ) ;
266+ void updateParams ( int level , int width , int height , int internalFormat , int type ) {
267+ if ( level > this .maxLevel ) {
268+ this . maxLevel = level ;
256269
257- needsUpdate |= vulkanImage == null ||
258- vulkanImage .width != width || vulkanImage .height != height ||
259- vkFormat != vulkanImage .format ;
270+ this .needsUpdate = true ;
271+ }
272+
273+ if (level == 0 ) {
274+ int vkFormat = GlUtil .vulkanFormat (internalFormat , type );
275+
276+ if (this .vulkanImage == null || this .width != width || this .height != height || vkFormat != vulkanImage .format ) {
277+ this .width = width ;
278+ this .height = height ;
279+ this .vkFormat = vkFormat ;
260280
281+ this .needsUpdate = true ;
282+ }
283+ }
284+ }
285+
286+ void allocateIfNeeded () {
261287 if (needsUpdate ) {
262288 allocateImage (width , height , vkFormat );
263289 updateSampler ();
@@ -270,17 +296,19 @@ void allocateImage(int width, int height, int vkFormat) {
270296 if (this .vulkanImage != null )
271297 this .vulkanImage .free ();
272298
273- if (VulkanImage .isDepthFormat (vkFormat ))
274- this .vulkanImage = VulkanImage .createDepthImage (vkFormat ,
275- width , height ,
299+ if (VulkanImage .isDepthFormat (vkFormat )) {
300+ this .vulkanImage = VulkanImage .createDepthImage (
301+ vkFormat , width , height ,
276302 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT ,
277303 false , true );
278- else
304+ }
305+ else {
279306 this .vulkanImage = new VulkanImage .Builder (width , height )
280307 .setMipLevels (maxLevel + 1 )
281308 .setFormat (vkFormat )
282309 .addUsage (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT )
283310 .createVulkanImage ();
311+ }
284312 }
285313
286314 void updateSampler () {
@@ -300,7 +328,7 @@ void updateSampler() {
300328 vulkanImage .updateTextureSampler (maxLod , samplerFlags );
301329 }
302330
303- private void uploadSubImage (int xOffset , int yOffset , int width , int height , int format , ByteBuffer pixels ) {
331+ private void uploadSubImage (int level , int xOffset , int yOffset , int width , int height , int format , ByteBuffer pixels ) {
304332 ByteBuffer src ;
305333 if (format == GL11 .GL_RGB && vulkanImage .format == VK_FORMAT_R8G8B8A8_UNORM ) {
306334 src = GlUtil .RGBtoRGBA_buffer (pixels );
@@ -310,7 +338,7 @@ private void uploadSubImage(int xOffset, int yOffset, int width, int height, int
310338 src = pixels ;
311339 }
312340
313- this .vulkanImage .uploadSubTextureAsync (0 , width , height , xOffset , yOffset , 0 , 0 , 0 , src );
341+ this .vulkanImage .uploadSubTextureAsync (level , width , height , xOffset , yOffset , unpackSkipRows , unpackSkipPixels , unpackRowLength , src );
314342
315343 if (src != pixels ) {
316344 MemoryUtil .memFree (src );
0 commit comments