Map renderer sampler state to OpenGL
This commit is contained in:
@@ -210,7 +210,8 @@ Known local toolchain state:
|
|||||||
texture-target mapping used by `TextureCube`.
|
texture-target mapping used by `TextureCube`.
|
||||||
It also owns and validates sampler wrap S/T/R, min/mag filter, and desktop
|
It also owns and validates sampler wrap S/T/R, min/mag filter, and desktop
|
||||||
border-color parameter mapping used by legacy `Sampler`, plus renderer API
|
border-color parameter mapping used by legacy `Sampler`, plus renderer API
|
||||||
sampler filter/address-mode to OpenGL token mapping including mirrored-repeat.
|
sampler filter/address-mode to OpenGL token mapping including mirrored-repeat
|
||||||
|
and aggregate renderer API sampler-state to OpenGL min/mag/wrap mapping.
|
||||||
The PanoPainter
|
The PanoPainter
|
||||||
shader attribute binding catalog, shader stage tokens, compile/link status
|
shader attribute binding catalog, shader stage tokens, compile/link status
|
||||||
queries, active-uniform count query, and matrix-uniform transpose token used
|
queries, active-uniform count query, and matrix-uniform transpose token used
|
||||||
|
|||||||
@@ -465,10 +465,11 @@ OpenGL texture-target mapping used by `TextureCube` also lives in
|
|||||||
`pp_renderer_gl`. The legacy app delegates extension, upload-format,
|
`pp_renderer_gl`. The legacy app delegates extension, upload-format,
|
||||||
framebuffer diagnostic, framebuffer blit, render-target setup, clear-state,
|
framebuffer diagnostic, framebuffer blit, render-target setup, clear-state,
|
||||||
2D/cube texture setup, mesh draw-mode, and cube-face texture-target
|
2D/cube texture setup, mesh draw-mode, and cube-face texture-target
|
||||||
interpretation to that backend library. Sampler wrap, min/mag filter, and desktop border-color parameter
|
interpretation to that backend library. Sampler wrap, min/mag filter, and
|
||||||
mapping for legacy `Sampler` also lives in `pp_renderer_gl`. Renderer API sampler
|
desktop border-color parameter mapping for legacy `Sampler` also lives in
|
||||||
filter/address-mode to OpenGL token mapping, including mirrored-repeat, is also
|
`pp_renderer_gl`. Renderer API sampler filter/address-mode to OpenGL token
|
||||||
tested there. The PanoPainter shader attribute
|
mapping, including mirrored-repeat, and aggregate renderer API sampler-state to
|
||||||
|
OpenGL min/mag/wrap mapping are also tested there. The PanoPainter shader attribute
|
||||||
binding catalog, shader stage tokens, compile/link status queries, active-uniform
|
binding catalog, shader stage tokens, compile/link status queries, active-uniform
|
||||||
count query, and matrix-uniform transpose token also live in `pp_renderer_gl`
|
count query, and matrix-uniform transpose token also live in `pp_renderer_gl`
|
||||||
and are consumed by legacy `Shader` creation. Renderer API blend factor/op to
|
and are consumed by legacy `Shader` creation. Renderer API blend factor/op to
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ constexpr std::uint32_t gl_texture_cube_map_negative_y = 0x8518U;
|
|||||||
constexpr std::uint32_t gl_texture_cube_map_positive_z = 0x8519U;
|
constexpr std::uint32_t gl_texture_cube_map_positive_z = 0x8519U;
|
||||||
constexpr std::uint32_t gl_texture_cube_map_negative_z = 0x851AU;
|
constexpr std::uint32_t gl_texture_cube_map_negative_z = 0x851AU;
|
||||||
constexpr std::uint32_t gl_linear = 0x2601U;
|
constexpr std::uint32_t gl_linear = 0x2601U;
|
||||||
|
constexpr std::uint32_t gl_nearest_mipmap_nearest = 0x2700U;
|
||||||
|
constexpr std::uint32_t gl_linear_mipmap_nearest = 0x2701U;
|
||||||
|
constexpr std::uint32_t gl_nearest_mipmap_linear = 0x2702U;
|
||||||
constexpr std::uint32_t gl_linear_mipmap_linear = 0x2703U;
|
constexpr std::uint32_t gl_linear_mipmap_linear = 0x2703U;
|
||||||
constexpr std::uint32_t gl_nearest = 0x2600U;
|
constexpr std::uint32_t gl_nearest = 0x2600U;
|
||||||
constexpr std::uint32_t gl_texture_mag_filter = 0x2800U;
|
constexpr std::uint32_t gl_texture_mag_filter = 0x2800U;
|
||||||
@@ -940,6 +943,34 @@ OpenGlEnumMapping sampler_filter_for_renderer_filter(pp::renderer::SamplerFilter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenGlEnumMapping sampler_min_filter_for_renderer_filters(
|
||||||
|
pp::renderer::SamplerFilter min_filter,
|
||||||
|
pp::renderer::SamplerFilter mip_filter) noexcept
|
||||||
|
{
|
||||||
|
switch (min_filter) {
|
||||||
|
case pp::renderer::SamplerFilter::nearest:
|
||||||
|
switch (mip_filter) {
|
||||||
|
case pp::renderer::SamplerFilter::nearest:
|
||||||
|
return OpenGlEnumMapping { .value = gl_nearest_mipmap_nearest, .supported = true };
|
||||||
|
case pp::renderer::SamplerFilter::linear:
|
||||||
|
return OpenGlEnumMapping { .value = gl_nearest_mipmap_linear, .supported = true };
|
||||||
|
default:
|
||||||
|
return OpenGlEnumMapping {};
|
||||||
|
}
|
||||||
|
case pp::renderer::SamplerFilter::linear:
|
||||||
|
switch (mip_filter) {
|
||||||
|
case pp::renderer::SamplerFilter::nearest:
|
||||||
|
return OpenGlEnumMapping { .value = gl_linear_mipmap_nearest, .supported = true };
|
||||||
|
case pp::renderer::SamplerFilter::linear:
|
||||||
|
return OpenGlEnumMapping { .value = gl_linear_mipmap_linear, .supported = true };
|
||||||
|
default:
|
||||||
|
return OpenGlEnumMapping {};
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return OpenGlEnumMapping {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OpenGlEnumMapping sampler_address_mode_for_renderer_mode(pp::renderer::SamplerAddressMode mode) noexcept
|
OpenGlEnumMapping sampler_address_mode_for_renderer_mode(pp::renderer::SamplerAddressMode mode) noexcept
|
||||||
{
|
{
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@@ -956,6 +987,28 @@ OpenGlEnumMapping sampler_address_mode_for_renderer_mode(pp::renderer::SamplerAd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenGlSamplerState sampler_state_for_renderer_sampler_desc(pp::renderer::SamplerDesc desc) noexcept
|
||||||
|
{
|
||||||
|
const auto min_filter = sampler_min_filter_for_renderer_filters(desc.min_filter, desc.mip_filter);
|
||||||
|
const auto mag_filter = sampler_filter_for_renderer_filter(desc.mag_filter);
|
||||||
|
const auto address_u = sampler_address_mode_for_renderer_mode(desc.address_u);
|
||||||
|
const auto address_v = sampler_address_mode_for_renderer_mode(desc.address_v);
|
||||||
|
const auto address_w = sampler_address_mode_for_renderer_mode(desc.address_w);
|
||||||
|
|
||||||
|
return OpenGlSamplerState {
|
||||||
|
.min_filter = min_filter.value,
|
||||||
|
.mag_filter = mag_filter.value,
|
||||||
|
.wrap_s = address_u.value,
|
||||||
|
.wrap_t = address_v.value,
|
||||||
|
.wrap_r = address_w.value,
|
||||||
|
.supported = min_filter.supported
|
||||||
|
&& mag_filter.supported
|
||||||
|
&& address_u.supported
|
||||||
|
&& address_v.supported
|
||||||
|
&& address_w.supported,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
std::uint32_t active_texture_unit(std::uint32_t unit_index) noexcept
|
std::uint32_t active_texture_unit(std::uint32_t unit_index) noexcept
|
||||||
{
|
{
|
||||||
return gl_texture0 + unit_index;
|
return gl_texture0 + unit_index;
|
||||||
|
|||||||
@@ -34,6 +34,15 @@ struct OpenGlTextureParameter {
|
|||||||
std::uint32_t value = 0;
|
std::uint32_t value = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OpenGlSamplerState {
|
||||||
|
std::uint32_t min_filter = 0;
|
||||||
|
std::uint32_t mag_filter = 0;
|
||||||
|
std::uint32_t wrap_s = 0;
|
||||||
|
std::uint32_t wrap_t = 0;
|
||||||
|
std::uint32_t wrap_r = 0;
|
||||||
|
bool supported = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct OpenGlViewportRect {
|
struct OpenGlViewportRect {
|
||||||
std::int32_t x = 0;
|
std::int32_t x = 0;
|
||||||
std::int32_t y = 0;
|
std::int32_t y = 0;
|
||||||
@@ -219,8 +228,13 @@ struct OpenGlWindowsWglContextConfig {
|
|||||||
[[nodiscard]] std::uint32_t clamp_to_border_texture_wrap() noexcept;
|
[[nodiscard]] std::uint32_t clamp_to_border_texture_wrap() noexcept;
|
||||||
[[nodiscard]] OpenGlEnumMapping sampler_filter_for_renderer_filter(
|
[[nodiscard]] OpenGlEnumMapping sampler_filter_for_renderer_filter(
|
||||||
pp::renderer::SamplerFilter filter) noexcept;
|
pp::renderer::SamplerFilter filter) noexcept;
|
||||||
|
[[nodiscard]] OpenGlEnumMapping sampler_min_filter_for_renderer_filters(
|
||||||
|
pp::renderer::SamplerFilter min_filter,
|
||||||
|
pp::renderer::SamplerFilter mip_filter) noexcept;
|
||||||
[[nodiscard]] OpenGlEnumMapping sampler_address_mode_for_renderer_mode(
|
[[nodiscard]] OpenGlEnumMapping sampler_address_mode_for_renderer_mode(
|
||||||
pp::renderer::SamplerAddressMode mode) noexcept;
|
pp::renderer::SamplerAddressMode mode) noexcept;
|
||||||
|
[[nodiscard]] OpenGlSamplerState sampler_state_for_renderer_sampler_desc(
|
||||||
|
pp::renderer::SamplerDesc desc) noexcept;
|
||||||
[[nodiscard]] std::uint32_t active_texture_unit(std::uint32_t unit_index) noexcept;
|
[[nodiscard]] std::uint32_t active_texture_unit(std::uint32_t unit_index) noexcept;
|
||||||
[[nodiscard]] std::uint32_t texture_cube_map_target() noexcept;
|
[[nodiscard]] std::uint32_t texture_cube_map_target() noexcept;
|
||||||
[[nodiscard]] std::uint32_t cube_map_allocation_face_texture_target(std::uint32_t face_index) noexcept;
|
[[nodiscard]] std::uint32_t cube_map_allocation_face_texture_target(std::uint32_t face_index) noexcept;
|
||||||
|
|||||||
@@ -440,6 +440,24 @@ void maps_renderer_sampler_tokens(pp::tests::Harness& h)
|
|||||||
pp::renderer::SamplerAddressMode::clamp_to_border);
|
pp::renderer::SamplerAddressMode::clamp_to_border);
|
||||||
const auto invalid_mode = pp::renderer::gl::sampler_address_mode_for_renderer_mode(
|
const auto invalid_mode = pp::renderer::gl::sampler_address_mode_for_renderer_mode(
|
||||||
static_cast<pp::renderer::SamplerAddressMode>(255U));
|
static_cast<pp::renderer::SamplerAddressMode>(255U));
|
||||||
|
const auto nearest_nearest = pp::renderer::gl::sampler_min_filter_for_renderer_filters(
|
||||||
|
pp::renderer::SamplerFilter::nearest,
|
||||||
|
pp::renderer::SamplerFilter::nearest);
|
||||||
|
const auto linear_nearest = pp::renderer::gl::sampler_min_filter_for_renderer_filters(
|
||||||
|
pp::renderer::SamplerFilter::linear,
|
||||||
|
pp::renderer::SamplerFilter::nearest);
|
||||||
|
const auto nearest_linear = pp::renderer::gl::sampler_min_filter_for_renderer_filters(
|
||||||
|
pp::renderer::SamplerFilter::nearest,
|
||||||
|
pp::renderer::SamplerFilter::linear);
|
||||||
|
const auto linear_linear = pp::renderer::gl::sampler_min_filter_for_renderer_filters(
|
||||||
|
pp::renderer::SamplerFilter::linear,
|
||||||
|
pp::renderer::SamplerFilter::linear);
|
||||||
|
const auto invalid_min_filter = pp::renderer::gl::sampler_min_filter_for_renderer_filters(
|
||||||
|
static_cast<pp::renderer::SamplerFilter>(255U),
|
||||||
|
pp::renderer::SamplerFilter::linear);
|
||||||
|
const auto invalid_mip_filter = pp::renderer::gl::sampler_min_filter_for_renderer_filters(
|
||||||
|
pp::renderer::SamplerFilter::linear,
|
||||||
|
static_cast<pp::renderer::SamplerFilter>(255U));
|
||||||
|
|
||||||
PP_EXPECT(h, nearest.supported);
|
PP_EXPECT(h, nearest.supported);
|
||||||
PP_EXPECT(h, nearest.value == 0x2600U);
|
PP_EXPECT(h, nearest.value == 0x2600U);
|
||||||
@@ -457,6 +475,58 @@ void maps_renderer_sampler_tokens(pp::tests::Harness& h)
|
|||||||
PP_EXPECT(h, clamp_to_border.value == 0x812DU);
|
PP_EXPECT(h, clamp_to_border.value == 0x812DU);
|
||||||
PP_EXPECT(h, !invalid_mode.supported);
|
PP_EXPECT(h, !invalid_mode.supported);
|
||||||
PP_EXPECT(h, invalid_mode.value == 0U);
|
PP_EXPECT(h, invalid_mode.value == 0U);
|
||||||
|
PP_EXPECT(h, nearest_nearest.supported);
|
||||||
|
PP_EXPECT(h, nearest_nearest.value == 0x2700U);
|
||||||
|
PP_EXPECT(h, linear_nearest.supported);
|
||||||
|
PP_EXPECT(h, linear_nearest.value == 0x2701U);
|
||||||
|
PP_EXPECT(h, nearest_linear.supported);
|
||||||
|
PP_EXPECT(h, nearest_linear.value == 0x2702U);
|
||||||
|
PP_EXPECT(h, linear_linear.supported);
|
||||||
|
PP_EXPECT(h, linear_linear.value == 0x2703U);
|
||||||
|
PP_EXPECT(h, !invalid_min_filter.supported);
|
||||||
|
PP_EXPECT(h, invalid_min_filter.value == 0U);
|
||||||
|
PP_EXPECT(h, !invalid_mip_filter.supported);
|
||||||
|
PP_EXPECT(h, invalid_mip_filter.value == 0U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void maps_renderer_sampler_states(pp::tests::Harness& h)
|
||||||
|
{
|
||||||
|
const auto default_sampler = pp::renderer::gl::sampler_state_for_renderer_sampler_desc(
|
||||||
|
pp::renderer::SamplerDesc {});
|
||||||
|
const auto mixed_sampler = pp::renderer::gl::sampler_state_for_renderer_sampler_desc(
|
||||||
|
pp::renderer::SamplerDesc {
|
||||||
|
.min_filter = pp::renderer::SamplerFilter::nearest,
|
||||||
|
.mag_filter = pp::renderer::SamplerFilter::linear,
|
||||||
|
.mip_filter = pp::renderer::SamplerFilter::linear,
|
||||||
|
.address_u = pp::renderer::SamplerAddressMode::repeat,
|
||||||
|
.address_v = pp::renderer::SamplerAddressMode::mirrored_repeat,
|
||||||
|
.address_w = pp::renderer::SamplerAddressMode::clamp_to_border,
|
||||||
|
});
|
||||||
|
const auto invalid_filter = pp::renderer::gl::sampler_state_for_renderer_sampler_desc(
|
||||||
|
pp::renderer::SamplerDesc {
|
||||||
|
.min_filter = static_cast<pp::renderer::SamplerFilter>(255U),
|
||||||
|
});
|
||||||
|
const auto invalid_address = pp::renderer::gl::sampler_state_for_renderer_sampler_desc(
|
||||||
|
pp::renderer::SamplerDesc {
|
||||||
|
.address_w = static_cast<pp::renderer::SamplerAddressMode>(255U),
|
||||||
|
});
|
||||||
|
|
||||||
|
PP_EXPECT(h, default_sampler.supported);
|
||||||
|
PP_EXPECT(h, default_sampler.min_filter == 0x2703U);
|
||||||
|
PP_EXPECT(h, default_sampler.mag_filter == 0x2601U);
|
||||||
|
PP_EXPECT(h, default_sampler.wrap_s == 0x812FU);
|
||||||
|
PP_EXPECT(h, default_sampler.wrap_t == 0x812FU);
|
||||||
|
PP_EXPECT(h, default_sampler.wrap_r == 0x812FU);
|
||||||
|
PP_EXPECT(h, mixed_sampler.supported);
|
||||||
|
PP_EXPECT(h, mixed_sampler.min_filter == 0x2702U);
|
||||||
|
PP_EXPECT(h, mixed_sampler.mag_filter == 0x2601U);
|
||||||
|
PP_EXPECT(h, mixed_sampler.wrap_s == 0x2901U);
|
||||||
|
PP_EXPECT(h, mixed_sampler.wrap_t == 0x8370U);
|
||||||
|
PP_EXPECT(h, mixed_sampler.wrap_r == 0x812DU);
|
||||||
|
PP_EXPECT(h, !invalid_filter.supported);
|
||||||
|
PP_EXPECT(h, invalid_filter.min_filter == 0U);
|
||||||
|
PP_EXPECT(h, !invalid_address.supported);
|
||||||
|
PP_EXPECT(h, invalid_address.wrap_r == 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exposes_shader_attribute_binding_catalog(pp::tests::Harness& h)
|
void exposes_shader_attribute_binding_catalog(pp::tests::Harness& h)
|
||||||
@@ -899,6 +969,7 @@ int main()
|
|||||||
harness.run("exposes_default_render_target_texture_parameters", exposes_default_render_target_texture_parameters);
|
harness.run("exposes_default_render_target_texture_parameters", exposes_default_render_target_texture_parameters);
|
||||||
harness.run("maps_sampler_parameters", maps_sampler_parameters);
|
harness.run("maps_sampler_parameters", maps_sampler_parameters);
|
||||||
harness.run("maps_renderer_sampler_tokens", maps_renderer_sampler_tokens);
|
harness.run("maps_renderer_sampler_tokens", maps_renderer_sampler_tokens);
|
||||||
|
harness.run("maps_renderer_sampler_states", maps_renderer_sampler_states);
|
||||||
harness.run("exposes_shader_attribute_binding_catalog", exposes_shader_attribute_binding_catalog);
|
harness.run("exposes_shader_attribute_binding_catalog", exposes_shader_attribute_binding_catalog);
|
||||||
harness.run("maps_app_initialization_parameters", maps_app_initialization_parameters);
|
harness.run("maps_app_initialization_parameters", maps_app_initialization_parameters);
|
||||||
harness.run("maps_renderer_viewports_and_scissors", maps_renderer_viewports_and_scissors);
|
harness.run("maps_renderer_viewports_and_scissors", maps_renderer_viewports_and_scissors);
|
||||||
|
|||||||
Reference in New Issue
Block a user