11package net .vulkanmod .vulkan .texture ;
22
3- import it .unimi .dsi .fastutil .shorts . Short2LongMap ;
4- import it .unimi .dsi .fastutil .shorts . Short2LongOpenHashMap ;
3+ import it .unimi .dsi .fastutil .objects . Object2LongMap ;
4+ import it .unimi .dsi .fastutil .objects . Object2LongOpenHashMap ;
55import net .vulkanmod .vulkan .device .DeviceManager ;
6- import org .apache .commons .lang3 .Validate ;
76import org .lwjgl .system .MemoryStack ;
87import org .lwjgl .vulkan .VkSamplerCreateInfo ;
98import org .lwjgl .vulkan .VkSamplerReductionModeCreateInfo ;
1312import static net .vulkanmod .vulkan .Vulkan .getVkDevice ;
1413import static org .lwjgl .system .MemoryStack .stackPush ;
1514import static org .lwjgl .vulkan .VK10 .*;
16- import static org .lwjgl .vulkan .VK12 .VK_SAMPLER_REDUCTION_MODE_MAX ;
17- import static org .lwjgl .vulkan .VK12 .VK_SAMPLER_REDUCTION_MODE_MIN ;
1815
1916public abstract class SamplerManager {
17+ public static final int ADDRESS_MODE_BITS = 2 ;
18+ public static final int REDUCTION_MODE_BITS = 2 ;
19+
20+ public static final int ADDRESS_MODE_U_OFFSET = 0 ;
21+ public static final int ADDRESS_MODE_V_OFFSET = 2 ;
22+ public static final int MIN_FILTER_OFFSET = 4 ;
23+ public static final int MAG_FILTER_OFFSET = 5 ;
24+ public static final int MIPMAP_MODE_OFFSET = 6 ;
25+ public static final int ANISOTROPY_OFFSET = 7 ;
26+ public static final int REDUCTION_MODE_ENABLE_OFFSET = 8 ;
27+ public static final int REDUCTION_MODE_OFFSET = 9 ;
28+
2029 static final float MIP_BIAS = -0.5f ;
2130
22- static final Short2LongMap SAMPLERS = new Short2LongOpenHashMap ();
31+ static final Object2LongMap <SamplerInfo > SAMPLERS = new Object2LongOpenHashMap <>();
32+
33+ public static long getSampler (boolean clamp , boolean linearFiltering , int maxLod ) {
34+ return getSampler (clamp , linearFiltering , maxLod , false , 0 );
35+ }
36+
37+ public static long getSampler (boolean clamp , boolean linearFiltering , int maxLod , boolean anisotropy , int maxAnisotropy ) {
38+ int addressMode = clamp ? VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : VK_SAMPLER_ADDRESS_MODE_REPEAT ;
39+ int filter = linearFiltering ? VK_FILTER_LINEAR : VK_FILTER_NEAREST ;
40+ int mipmapMode = linearFiltering ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST ;
41+
42+ return getSampler (addressMode , addressMode , filter , filter , mipmapMode , maxLod , anisotropy , maxAnisotropy , -1 );
43+ }
44+
45+ public static long getSampler (int addressModeU , int addressModeV ,
46+ int minFilter , int magFilter , int mipmapMode , float maxLod ,
47+ boolean anisotropy , float maxAnisotropy , int reductionMode ) {
48+ SamplerInfo samplerInfo = new SamplerInfo (addressModeU , addressModeV , minFilter , magFilter , mipmapMode , maxLod , anisotropy , maxAnisotropy , reductionMode );
2349
24- public static long getTextureSampler (byte maxLod , byte flags ) {
25- short key = (short ) (flags | (maxLod << 8 ));
26- long sampler = SAMPLERS .getOrDefault (key , 0L );
50+ long sampler = SAMPLERS .getOrDefault (samplerInfo , 0L );
2751
2852 if (sampler == 0L ) {
29- sampler = createTextureSampler (maxLod , flags );
30- SAMPLERS .put (key , sampler );
53+ sampler = createTextureSampler (samplerInfo );
54+ SAMPLERS .put (samplerInfo , sampler );
3155 }
3256
3357 return sampler ;
3458 }
3559
36- private static long createTextureSampler (byte maxLod , byte flags ) {
37- Validate .isTrue (
38- (flags & (REDUCTION_MIN_BIT | REDUCTION_MAX_BIT )) != (REDUCTION_MIN_BIT | REDUCTION_MAX_BIT )
39- );
60+ public static long getDefaultSampler () {
61+ return getSampler (false , false , 0 );
62+ }
4063
41- try (MemoryStack stack = stackPush ()) {
64+ private static long createTextureSampler (SamplerInfo sampler ) {
65+ int state = sampler .encodedState ;
4266
67+ try (MemoryStack stack = stackPush ()) {
4368 VkSamplerCreateInfo samplerInfo = VkSamplerCreateInfo .calloc (stack );
4469 samplerInfo .sType (VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO );
4570
46- if ((flags & LINEAR_FILTERING_BIT ) != 0 ) {
47- samplerInfo .magFilter (VK_FILTER_LINEAR );
48- samplerInfo .minFilter (VK_FILTER_LINEAR );
49- } else {
50- samplerInfo .magFilter (VK_FILTER_NEAREST );
51- samplerInfo .minFilter (VK_FILTER_NEAREST );
52- }
71+ samplerInfo .magFilter (sampler .getMagFilter ());
72+ samplerInfo .minFilter (sampler .getMinFilter ());
5373
54- if ((flags & CLAMP_BIT ) != 0 ) {
55- samplerInfo .addressModeU (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE );
56- samplerInfo .addressModeV (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE );
57- samplerInfo .addressModeW (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE );
58- } else {
59- samplerInfo .addressModeU (VK_SAMPLER_ADDRESS_MODE_REPEAT );
60- samplerInfo .addressModeV (VK_SAMPLER_ADDRESS_MODE_REPEAT );
61- samplerInfo .addressModeW (VK_SAMPLER_ADDRESS_MODE_REPEAT );
62- }
74+ samplerInfo .addressModeU (sampler .getAddressModeU ());
75+ samplerInfo .addressModeV (sampler .getAddressModeV ());
76+ samplerInfo .addressModeW (VK_SAMPLER_ADDRESS_MODE_REPEAT );
6377
64- samplerInfo .anisotropyEnable (false );
65- // samplerInfo.maxAnisotropy(16.0f );
78+ samplerInfo .anisotropyEnable (sampler . getAnisotropy () );
79+ samplerInfo .maxAnisotropy (sampler . getMaxAnisotropy () );
6680 samplerInfo .borderColor (VK_BORDER_COLOR_INT_OPAQUE_WHITE );
6781 samplerInfo .unnormalizedCoordinates (false );
6882 samplerInfo .compareEnable (false );
6983 samplerInfo .compareOp (VK_COMPARE_OP_ALWAYS );
7084
71- if ((flags & USE_MIPMAPS_BIT ) == 0 ) {
72- samplerInfo .mipmapMode (VK_SAMPLER_MIPMAP_MODE_NEAREST );
73- samplerInfo .maxLod (0.0F );
74- samplerInfo .minLod (0.0F );
75- } else {
76- if ((flags & MIPMAP_LINEAR_FILTERING_BIT ) != 0 ) {
77- samplerInfo .mipmapMode (VK_SAMPLER_MIPMAP_MODE_LINEAR );
78- } else {
79- samplerInfo .mipmapMode (VK_SAMPLER_MIPMAP_MODE_NEAREST );
80- }
81- samplerInfo .maxLod (maxLod );
82- samplerInfo .minLod (0.0F );
83- samplerInfo .mipLodBias (MIP_BIAS );
84- }
85+ samplerInfo .mipmapMode (sampler .getMipmapMode ());
86+ samplerInfo .maxLod (sampler .getMaxLod ());
87+ samplerInfo .minLod (0.0F );
88+ samplerInfo .mipLodBias (MIP_BIAS );
8589
86- //Reduction Mode
87- if (( flags & ( REDUCTION_MAX_BIT | REDUCTION_MIN_BIT )) != 0 ) {
90+ // Reduction Mode
91+ if (sampler . hasReductionMode () ) {
8892 VkSamplerReductionModeCreateInfo reductionModeInfo = VkSamplerReductionModeCreateInfo .calloc (stack );
8993 reductionModeInfo .sType$Default ();
90- reductionModeInfo .reductionMode (( flags & REDUCTION_MAX_BIT ) != 0 ? VK_SAMPLER_REDUCTION_MODE_MAX : VK_SAMPLER_REDUCTION_MODE_MIN );
94+ reductionModeInfo .reductionMode (sampler . getReductionMode () );
9195 samplerInfo .pNext (reductionModeInfo .address ());
9296 }
9397
@@ -107,10 +111,91 @@ public static void cleanUp() {
107111 }
108112 }
109113
110- public static final byte LINEAR_FILTERING_BIT = 0b1;
111- public static final byte CLAMP_BIT = 0b10;
112- public static final byte USE_MIPMAPS_BIT = 0b100;
113- public static final byte MIPMAP_LINEAR_FILTERING_BIT = 0b1000;
114- public static final byte REDUCTION_MIN_BIT = 0b10000;
115- public static final byte REDUCTION_MAX_BIT = 0b100000;
114+ public static class SamplerInfo {
115+ final int encodedState ;
116+ final int maxLod ;
117+ final int maxAnisotropy ;
118+
119+ public SamplerInfo () {
120+ this (VK_SAMPLER_ADDRESS_MODE_REPEAT , VK_SAMPLER_ADDRESS_MODE_REPEAT ,
121+ VK_FILTER_NEAREST , VK_FILTER_NEAREST , VK_SAMPLER_MIPMAP_MODE_NEAREST ,
122+ 0 , false , 0 , -1 );
123+ }
124+
125+
126+
127+ public SamplerInfo (int addressModeU , int addressModeV , int minFilter , int magFilter , int mipmapMode ,
128+ float maxLod , boolean anisotropy , float maxAnisotropy , int reductionMode ) {
129+ this .maxLod = (int ) maxLod ;
130+ this .maxAnisotropy = (int ) maxAnisotropy ;
131+
132+ int encodedState = (addressModeU & ADDRESS_MODE_BITS ) << ADDRESS_MODE_U_OFFSET ;
133+ encodedState |= (addressModeV & ADDRESS_MODE_BITS ) << ADDRESS_MODE_V_OFFSET ;
134+ encodedState |= (minFilter & 1 ) << MIN_FILTER_OFFSET ;
135+ encodedState |= (magFilter & 1 ) << MAG_FILTER_OFFSET ;
136+ encodedState |= (mipmapMode & 1 ) << MIPMAP_MODE_OFFSET ;
137+ encodedState |= ((anisotropy ? 1 : 0 ) & 1 ) << ANISOTROPY_OFFSET ;
138+ encodedState |= (reductionMode != -1 ? 1 : 0 ) << REDUCTION_MODE_ENABLE_OFFSET ;
139+ encodedState |= (reductionMode & REDUCTION_MODE_BITS ) << REDUCTION_MODE_OFFSET ;
140+
141+ this .encodedState = encodedState ;
142+ }
143+
144+ public int getAddressModeU () {
145+ return (this .encodedState >> ADDRESS_MODE_U_OFFSET ) & ADDRESS_MODE_BITS ;
146+ }
147+
148+ public int getAddressModeV () {
149+ return (this .encodedState >> ADDRESS_MODE_V_OFFSET ) & ADDRESS_MODE_BITS ;
150+ }
151+
152+ public int getMinFilter () {
153+ return (this .encodedState >> MIN_FILTER_OFFSET ) & 1 ;
154+ }
155+
156+ public int getMagFilter () {
157+ return (this .encodedState >> MAG_FILTER_OFFSET ) & 1 ;
158+ }
159+
160+ public int getMipmapMode () {
161+ return (this .encodedState >> MIPMAP_MODE_OFFSET ) & 1 ;
162+ }
163+
164+ public boolean getAnisotropy () {
165+ return ((this .encodedState >> ANISOTROPY_OFFSET ) & 1 ) != 0 ;
166+ }
167+
168+ public boolean hasReductionMode () {
169+ return ((this .encodedState >> REDUCTION_MODE_ENABLE_OFFSET ) & 1 ) != 0 ;
170+ }
171+
172+ public int getReductionMode () {
173+ return (this .encodedState >> REDUCTION_MODE_OFFSET ) & REDUCTION_MODE_BITS ;
174+ }
175+
176+ public int getMaxAnisotropy () {
177+ return maxAnisotropy ;
178+ }
179+
180+ public int getMaxLod () {
181+ return maxLod ;
182+ }
183+
184+ @ Override
185+ public boolean equals (Object o ) {
186+ if (o == null || getClass () != o .getClass ()) return false ;
187+
188+ SamplerInfo samplerInfo = (SamplerInfo ) o ;
189+ return maxLod == samplerInfo .maxLod && maxAnisotropy == samplerInfo .maxAnisotropy && encodedState == samplerInfo .encodedState ;
190+ }
191+
192+ @ Override
193+ public int hashCode () {
194+ int result = encodedState ;
195+ result = 31 * result + maxLod ;
196+ result = 31 * result + maxAnisotropy ;
197+ return result ;
198+ }
199+ }
200+
116201}
0 commit comments