mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-10 22:05:06 +00:00
gs-mipmapper: Implement actual mipmap generation
This enables full mipmapping support for textures with a shader view that allows accessing different mip levels. In order to access mip levels, you have to specify gs::texture:🎏:BuildMipMaps when creating the texture, as OBS currently forces the maximum mip level to 1 even if you actually have mip data available.
This commit is contained in:
parent
c591902fea
commit
7c520ae9ee
2 changed files with 60 additions and 40 deletions
|
@ -77,7 +77,7 @@ float4 PSSharpen(VertDataOut v_in) : TARGET
|
||||||
|
|
||||||
float4 PSSmoothen(VertDataOut v_in) : TARGET
|
float4 PSSmoothen(VertDataOut v_in) : TARGET
|
||||||
{
|
{
|
||||||
// If we use bilinear and linear sampling, we can get away with just 4 total sampler queries.
|
// If we use linear sampling, we can get away with just 4 total sampler queries.
|
||||||
// However this is not a cheap implementation, it's just meant to be accurate so we do each sampler query and rely on the compiler.
|
// However this is not a cheap implementation, it's just meant to be accurate so we do each sampler query and rely on the compiler.
|
||||||
|
|
||||||
float3 smoothKernel3 = float3(0.0574428, 0.0947072, 0.3914000);
|
float3 smoothKernel3 = float3(0.0574428, 0.0947072, 0.3914000);
|
||||||
|
|
|
@ -181,25 +181,32 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
|
||||||
size_t texture_height = source->get_height();
|
size_t texture_height = source->get_height();
|
||||||
float_t texel_width = 1.0 / texture_width;
|
float_t texel_width = 1.0 / texture_width;
|
||||||
float_t texel_height = 1.0 / texture_height;
|
float_t texel_height = 1.0 / texture_height;
|
||||||
|
size_t mip_levels = 1;
|
||||||
|
|
||||||
#if defined(WIN32) || defined(WIN64)
|
#if defined(WIN32) || defined(WIN64)
|
||||||
|
ID3D11Texture2D* target_t2;
|
||||||
|
ID3D11Texture2D* source_t2;
|
||||||
if (device_type == GS_DEVICE_DIRECT3D_11) {
|
if (device_type == GS_DEVICE_DIRECT3D_11) {
|
||||||
// We definitely have a Direct3D11 resource.
|
// We definitely have a Direct3D11 resource.
|
||||||
D3D11_TEXTURE2D_DESC target_t2desc;
|
D3D11_TEXTURE2D_DESC target_t2desc;
|
||||||
ID3D11Texture2D* target_t2 = reinterpret_cast<ID3D11Texture2D*>(tobj);
|
target_t2 = reinterpret_cast<ID3D11Texture2D*>(tobj);
|
||||||
ID3D11Texture2D* source_t2 = reinterpret_cast<ID3D11Texture2D*>(sobj);
|
source_t2 = reinterpret_cast<ID3D11Texture2D*>(sobj);
|
||||||
|
|
||||||
target_t2->GetDesc(&target_t2desc);
|
target_t2->GetDesc(&target_t2desc);
|
||||||
|
|
||||||
dev->context->CopySubresourceRegion(target_t2, 0, 0, 0, 0, source_t2, 0, nullptr);
|
dev->context->CopySubresourceRegion(target_t2, 0, 0, 0, 0, source_t2, 0, nullptr);
|
||||||
|
mip_levels = target_t2desc.MipLevels;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (device_type == GS_DEVICE_OPENGL) {
|
||||||
|
// This is an OpenGL resource.
|
||||||
|
}
|
||||||
|
|
||||||
// If we do not have any miplevels, just stop now.
|
// If we do not have any miplevels, just stop now.
|
||||||
if (target_t2desc.MipLevels == 1) {
|
if (mip_levels == 1) {
|
||||||
obs_leave_graphics();
|
obs_leave_graphics();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t mip = 1; mip <= target_t2desc.MipLevels; mip++) {
|
for (size_t mip = 1; mip < mip_levels; mip++) {
|
||||||
texture_width /= 2;
|
texture_width /= 2;
|
||||||
texture_height /= 2;
|
texture_height /= 2;
|
||||||
texel_width *= 2;
|
texel_width *= 2;
|
||||||
|
@ -209,8 +216,22 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
|
||||||
try {
|
try {
|
||||||
auto op = render_target->render(texture_width, texture_height);
|
auto op = render_target->render(texture_width, texture_height);
|
||||||
|
|
||||||
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
|
gs_reset_blend_state();
|
||||||
|
gs_blend_function_separate(gs_blend_type::GS_BLEND_ONE, gs_blend_type::GS_BLEND_ZERO,
|
||||||
|
gs_blend_type::GS_BLEND_ONE, gs_blend_type::GS_BLEND_ZERO);
|
||||||
|
gs_enable_depth_test(false);
|
||||||
|
gs_enable_stencil_test(false);
|
||||||
|
gs_enable_stencil_write(false);
|
||||||
|
gs_enable_color(true, true, true, true);
|
||||||
|
gs_ortho(0, 1, 0, 1, -1, 1);
|
||||||
|
|
||||||
|
vec4 black;
|
||||||
|
vec4_zero(&black);
|
||||||
|
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0);
|
||||||
|
|
||||||
effect->get_parameter("image").set_texture(target);
|
effect->get_parameter("image").set_texture(target);
|
||||||
effect->get_parameter("level").set_int(mip);
|
effect->get_parameter("level").set_int(mip - 1);
|
||||||
effect->get_parameter("imageTexel").set_float2(texel_width, texel_height);
|
effect->get_parameter("imageTexel").set_float2(texel_width, texel_height);
|
||||||
effect->get_parameter("strength").set_float(strength);
|
effect->get_parameter("strength").set_float(strength);
|
||||||
|
|
||||||
|
@ -221,16 +242,15 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
|
||||||
P_LOG_ERROR("Failed to render mipmap layer.");
|
P_LOG_ERROR("Failed to render mipmap layer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(WIN64)
|
||||||
|
if (device_type == GS_DEVICE_DIRECT3D_11) {
|
||||||
// Copy
|
// Copy
|
||||||
ID3D11Texture2D* rt =
|
ID3D11Texture2D* rt =
|
||||||
reinterpret_cast<ID3D11Texture2D*>(gs_texture_get_obj(render_target->get_object()));
|
reinterpret_cast<ID3D11Texture2D*>(gs_texture_get_obj(render_target->get_object()));
|
||||||
uint32_t level = D3D11CalcSubresource(mip, 0, target_t2desc.MipLevels);
|
uint32_t level = D3D11CalcSubresource(mip, 0, mip_levels);
|
||||||
dev->context->CopySubresourceRegion(target_t2, level, 0, 0, 0, rt, 0, NULL);
|
dev->context->CopySubresourceRegion(target_t2, level, 0, 0, 0, rt, 0, NULL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (device_type == GS_DEVICE_OPENGL) {
|
|
||||||
// This is an OpenGL resource.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue