-
-
Notifications
You must be signed in to change notification settings - Fork 345
nv2a: Implement texture LOD bias #2435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,4 +64,13 @@ hwaddr pgraph_get_texture_palette_phys_addr_length(PGRAPHState *pg, int texture_ | |
TextureShape pgraph_get_texture_shape(PGRAPHState *pg, int texture_idx); | ||
size_t pgraph_get_texture_length(PGRAPHState *pg, TextureShape *shape); | ||
|
||
static inline float pgraph_convert_lod_bias_to_float(uint32_t lod_bias) | ||
{ | ||
int sign_extended_bias = lod_bias; | ||
if (lod_bias & (1 << 12)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this 12th bit have any significant name or is it merely tested to "or in" the subsequent 0x00001FFF const? And whats the significance of that? Fixed point ceiling, because of the final division by 256.0f ? Xemu is not strong in code comments but this looks like a hard to maintain bit of logic of anyone ever needs to revisit this again. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never mind, it is actually doing sign extension on the 12th bit onwards, assuming the trust contains a 12 bit signed fixed point number (4 integer + 8 fractional bits, in twos complement, a.k.a. Q3.8). Apparently there's no helper function for that yet. Just 1 thought: the output range is now -8.0 to +7.99609375 which is not exactly 8.0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think there are many places where 5.8 fixed point numbers are used and it doesn't seem clearly useful to bother with a more complicated generic sign extended fixed point -> float conversion function. I also doubt it'd 7.99609375 versus 8 would result in noticeable differences if it actually ends up being materially different from how the nv2a HW handles the 5.8 value. I'd guess there's likely more variance across HW/drivers than that fractional delta in any case. |
||
sign_extended_bias |= ~NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS; | ||
} | ||
return (float)sign_extended_bias / 256.f; | ||
} | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1336,6 +1336,14 @@ static void create_texture(PGRAPHState *pg, int texture_idx) | |
min_filter == NV_PGRAPH_TEXFILTER0_MIN_BOX_NEARESTLOD || | ||
min_filter == NV_PGRAPH_TEXFILTER0_MIN_TENT_NEARESTLOD; | ||
|
||
float lod_bias = pgraph_convert_lod_bias_to_float( | ||
GET_MASK(filter, NV_PGRAPH_TEXFILTER0_MIPMAP_LOD_BIAS)); | ||
if (lod_bias > r->device_props.limits.maxSamplerLodBias) { | ||
lod_bias = r->device_props.limits.maxSamplerLodBias; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to also handle negative bias clamp (absolute value must not exceed maxSamplerLodBias) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, misread your comment, sorry! That said, is it actually necessary to manually clamp these at the application level? The docs lead me to believe that the driver would handle the clamping, since it ends up being a summation of the bias and the sampling so simply clamping the bias may be insufficient to remain in bounds anyway:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Maybe, maybe not. According to spec: The absolute value of mipLodBias must be less than or equal to VkPhysicalDeviceLimits::maxSamplerLodBias
In general, Vulkan drivers are a lot less forgiving. Even when operating fully within spec, they can be problematic. If we are lucky, a case like this would trigger a validation warning and have no other impact, if we are unlucky it results in some random overflow and a crash, so it's best to follow spec guidance when populating struct params. |
||
} else if (lod_bias < -r->device_props.limits.maxSamplerLodBias) { | ||
lod_bias = -r->device_props.limits.maxSamplerLodBias; | ||
} | ||
|
||
VkSamplerCreateInfo sampler_create_info = { | ||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, | ||
.magFilter = vk_mag_filter, | ||
|
@@ -1356,7 +1364,7 @@ static void create_texture(PGRAPHState *pg, int texture_idx) | |
VK_SAMPLER_MIPMAP_MODE_LINEAR, | ||
.minLod = mipmap_en ? MIN(state.min_mipmap_level, state.levels - 1) : 0.0, | ||
.maxLod = mipmap_en ? MIN(state.max_mipmap_level, state.levels - 1) : 0.0, | ||
.mipLodBias = 0.0, | ||
.mipLodBias = lod_bias, | ||
.pNext = sampler_next_struct, | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
binding->lod_bias
not initialized?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, done.