Route cube textures and samplers through renderer GL
This commit is contained in:
@@ -212,6 +212,9 @@ Known local toolchain state:
|
||||
border-color parameter mapping used by legacy `Sampler`, plus renderer API
|
||||
sampler filter/address-mode to OpenGL token mapping including mirrored-repeat
|
||||
and aggregate renderer API sampler-state to OpenGL min/mag/wrap mapping.
|
||||
Legacy `TextureCube` allocation/bind/delete and legacy `Sampler`
|
||||
create/configure/border/bind/unbind calls now consume those resource dispatch
|
||||
contracts directly from the retained app utilities.
|
||||
The PanoPainter
|
||||
shader attribute binding catalog, shader stage tokens, compile/link status
|
||||
queries, active-uniform count query, and matrix-uniform transpose token used
|
||||
|
||||
@@ -1109,6 +1109,10 @@ Results:
|
||||
Sampler parameter validation covers wrap S/T/R plus min/mag filter ordering
|
||||
used by legacy `Sampler::set` and `Sampler::set_filter`, plus the desktop
|
||||
border-color parameter name used by `Sampler::set_border`.
|
||||
Legacy `TextureCube` allocation/bind/delete and `Sampler`
|
||||
create/configure/border/bind/unbind paths now execute through tested
|
||||
`pp_renderer_gl` dispatch contracts, keeping cube-map and sampler resource
|
||||
lifecycle reachable without a live GL context.
|
||||
Shader attribute binding catalog validation covers the current `pos`, `uvs`,
|
||||
`uvs2`, `col`, and `nor` bindings and rejects empty, unnamed, null-name, and
|
||||
duplicate-name catalogs while preserving legacy shared locations. Shader
|
||||
|
||||
@@ -480,6 +480,65 @@ pp::foundation::Status delete_opengl_texture_2d(
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status delete_opengl_texture_objects(
|
||||
std::span<const std::uint32_t> texture_ids,
|
||||
OpenGlTexture2DDeleteDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.delete_textures == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL texture delete dispatch callback must not be null");
|
||||
}
|
||||
|
||||
if (texture_ids.empty()) {
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
dispatch.delete_textures(static_cast<std::uint32_t>(texture_ids.size()), texture_ids.data());
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Result<std::uint32_t> allocate_opengl_texture_cube(
|
||||
OpenGlTextureCubeAllocation allocation,
|
||||
OpenGlTextureCubeAllocationDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.gen_textures == nullptr
|
||||
|| dispatch.bind_texture == nullptr
|
||||
|| dispatch.tex_image_2d == nullptr) {
|
||||
return pp::foundation::Result<std::uint32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument(
|
||||
"OpenGL cube texture allocation dispatch callbacks must not be null"));
|
||||
}
|
||||
|
||||
if (allocation.resolution <= 0
|
||||
|| allocation.internal_format == 0
|
||||
|| allocation.pixel_format == 0U
|
||||
|| allocation.component_type == 0U) {
|
||||
return pp::foundation::Result<std::uint32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL cube texture allocation parameters are invalid"));
|
||||
}
|
||||
|
||||
std::uint32_t texture_id = 0U;
|
||||
dispatch.gen_textures(1U, &texture_id);
|
||||
if (texture_id == 0U) {
|
||||
return pp::foundation::Result<std::uint32_t>::failure(
|
||||
pp::foundation::Status::out_of_range("OpenGL cube texture allocation returned id 0"));
|
||||
}
|
||||
|
||||
dispatch.bind_texture(texture_cube_map_target(), texture_id);
|
||||
for (std::uint32_t face_index = 0U; face_index < 6U; ++face_index) {
|
||||
dispatch.tex_image_2d(
|
||||
cube_map_allocation_face_texture_target(face_index),
|
||||
0,
|
||||
allocation.internal_format,
|
||||
allocation.resolution,
|
||||
allocation.resolution,
|
||||
0,
|
||||
allocation.pixel_format,
|
||||
allocation.component_type,
|
||||
nullptr);
|
||||
}
|
||||
return pp::foundation::Result<std::uint32_t>::success(texture_id);
|
||||
}
|
||||
|
||||
pp::foundation::Status bind_opengl_texture_2d(
|
||||
std::uint32_t texture_id,
|
||||
OpenGlTexture2DBindDispatch dispatch) noexcept
|
||||
@@ -492,6 +551,18 @@ pp::foundation::Status bind_opengl_texture_2d(
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status bind_opengl_texture_cube(
|
||||
std::uint32_t texture_id,
|
||||
OpenGlTexture2DBindDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.bind_texture == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL cube texture bind dispatch callback must not be null");
|
||||
}
|
||||
|
||||
dispatch.bind_texture(texture_cube_map_target(), texture_id);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status update_opengl_texture_2d(
|
||||
OpenGlTexture2DUpdate update,
|
||||
OpenGlTexture2DUpdateDispatch dispatch) noexcept
|
||||
@@ -714,6 +785,104 @@ pp::foundation::Status restore_opengl_framebuffer_binding(
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Result<std::uint32_t> create_opengl_sampler(
|
||||
std::span<const OpenGlTextureParameter> parameters,
|
||||
OpenGlSamplerCreateDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.gen_samplers == nullptr || dispatch.sampler_parameter_i == nullptr) {
|
||||
return pp::foundation::Result<std::uint32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL sampler create dispatch callbacks must not be null"));
|
||||
}
|
||||
|
||||
if (parameters.empty()) {
|
||||
return pp::foundation::Result<std::uint32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL sampler parameters are invalid"));
|
||||
}
|
||||
|
||||
for (const auto parameter : parameters) {
|
||||
if (parameter.name == 0U) {
|
||||
return pp::foundation::Result<std::uint32_t>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL sampler parameter name is invalid"));
|
||||
}
|
||||
}
|
||||
|
||||
std::uint32_t sampler_id = 0U;
|
||||
dispatch.gen_samplers(1U, &sampler_id);
|
||||
if (sampler_id == 0U) {
|
||||
return pp::foundation::Result<std::uint32_t>::failure(
|
||||
pp::foundation::Status::out_of_range("OpenGL sampler allocation returned id 0"));
|
||||
}
|
||||
|
||||
const auto status = set_opengl_sampler_parameters(
|
||||
sampler_id,
|
||||
parameters,
|
||||
OpenGlSamplerParameterDispatch {
|
||||
.sampler_parameter_i = dispatch.sampler_parameter_i,
|
||||
});
|
||||
if (!status.ok()) {
|
||||
return pp::foundation::Result<std::uint32_t>::failure(status);
|
||||
}
|
||||
|
||||
return pp::foundation::Result<std::uint32_t>::success(sampler_id);
|
||||
}
|
||||
|
||||
pp::foundation::Status set_opengl_sampler_parameters(
|
||||
std::uint32_t sampler_id,
|
||||
std::span<const OpenGlTextureParameter> parameters,
|
||||
OpenGlSamplerParameterDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.sampler_parameter_i == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL sampler parameter dispatch callback must not be null");
|
||||
}
|
||||
|
||||
if (sampler_id == 0U || parameters.empty()) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL sampler parameters are invalid");
|
||||
}
|
||||
|
||||
for (const auto parameter : parameters) {
|
||||
if (parameter.name == 0U) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL sampler parameter name is invalid");
|
||||
}
|
||||
dispatch.sampler_parameter_i(
|
||||
sampler_id,
|
||||
parameter.name,
|
||||
static_cast<std::int32_t>(parameter.value));
|
||||
}
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status set_opengl_sampler_border_color(
|
||||
std::uint32_t sampler_id,
|
||||
std::uint32_t parameter,
|
||||
const float* rgba,
|
||||
OpenGlSamplerBorderDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.sampler_parameter_fv == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument(
|
||||
"OpenGL sampler border color dispatch callback must not be null");
|
||||
}
|
||||
|
||||
if (sampler_id == 0U || parameter == 0U || rgba == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL sampler border color parameters are invalid");
|
||||
}
|
||||
|
||||
dispatch.sampler_parameter_fv(sampler_id, parameter, rgba);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status bind_opengl_sampler_object(
|
||||
std::uint32_t unit,
|
||||
std::uint32_t sampler_id,
|
||||
OpenGlSamplerBindDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.bind_sampler == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL sampler bind dispatch callback must not be null");
|
||||
}
|
||||
|
||||
dispatch.bind_sampler(unit, sampler_id);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
std::uint32_t extension_count_query() noexcept
|
||||
{
|
||||
return gl_num_extensions;
|
||||
|
||||
@@ -119,6 +119,13 @@ struct OpenGlTexture2DAllocation {
|
||||
const void* data = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlTextureCubeAllocation {
|
||||
std::int32_t resolution = 0;
|
||||
std::int32_t internal_format = 0;
|
||||
std::uint32_t pixel_format = 0;
|
||||
std::uint32_t component_type = 0;
|
||||
};
|
||||
|
||||
struct OpenGlTexture2DUpdate {
|
||||
std::uint32_t texture_id = 0;
|
||||
std::int32_t width = 0;
|
||||
@@ -216,6 +223,14 @@ using OpenGlUseProgramFn = void (*)(std::uint32_t program) noexcept;
|
||||
using OpenGlBindFramebufferFn = void (*)(std::uint32_t target, std::uint32_t framebuffer) noexcept;
|
||||
using OpenGlBindTextureFn = void (*)(std::uint32_t target, std::uint32_t texture) noexcept;
|
||||
using OpenGlBindSamplerFn = void (*)(std::uint32_t unit, std::uint32_t sampler) noexcept;
|
||||
using OpenGlSamplerParameteriFn = void (*)(
|
||||
std::uint32_t sampler,
|
||||
std::uint32_t parameter,
|
||||
std::int32_t value) noexcept;
|
||||
using OpenGlSamplerParameterfvFn = void (*)(
|
||||
std::uint32_t sampler,
|
||||
std::uint32_t parameter,
|
||||
const float* values) noexcept;
|
||||
using OpenGlGenObjectsFn = void (*)(std::uint32_t count, std::uint32_t* ids) noexcept;
|
||||
using OpenGlDeleteObjectsFn = void (*)(std::uint32_t count, const std::uint32_t* ids) noexcept;
|
||||
using OpenGlTexImage2DFn = void (*)(
|
||||
@@ -349,6 +364,12 @@ struct OpenGlTexture2DDeleteDispatch {
|
||||
OpenGlDeleteObjectsFn delete_textures = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlTextureCubeAllocationDispatch {
|
||||
OpenGlGenObjectsFn gen_textures = nullptr;
|
||||
OpenGlBindTextureFn bind_texture = nullptr;
|
||||
OpenGlTexImage2DFn tex_image_2d = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlTexture2DBindDispatch {
|
||||
OpenGlBindTextureFn bind_texture = nullptr;
|
||||
};
|
||||
@@ -395,6 +416,23 @@ struct OpenGlFramebufferRestoreDispatch {
|
||||
OpenGlBindFramebufferFn bind_framebuffer = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlSamplerCreateDispatch {
|
||||
OpenGlGenObjectsFn gen_samplers = nullptr;
|
||||
OpenGlSamplerParameteriFn sampler_parameter_i = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlSamplerParameterDispatch {
|
||||
OpenGlSamplerParameteriFn sampler_parameter_i = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlSamplerBorderDispatch {
|
||||
OpenGlSamplerParameterfvFn sampler_parameter_fv = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlSamplerBindDispatch {
|
||||
OpenGlBindSamplerFn bind_sampler = nullptr;
|
||||
};
|
||||
|
||||
[[nodiscard]] OpenGlCapabilities detect_opengl_capabilities(
|
||||
std::span<const std::string_view> extensions,
|
||||
OpenGlRuntime runtime) noexcept;
|
||||
@@ -433,9 +471,18 @@ struct OpenGlFramebufferRestoreDispatch {
|
||||
[[nodiscard]] pp::foundation::Status delete_opengl_texture_2d(
|
||||
std::uint32_t texture_id,
|
||||
OpenGlTexture2DDeleteDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status delete_opengl_texture_objects(
|
||||
std::span<const std::uint32_t> texture_ids,
|
||||
OpenGlTexture2DDeleteDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<std::uint32_t> allocate_opengl_texture_cube(
|
||||
OpenGlTextureCubeAllocation allocation,
|
||||
OpenGlTextureCubeAllocationDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status bind_opengl_texture_2d(
|
||||
std::uint32_t texture_id,
|
||||
OpenGlTexture2DBindDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status bind_opengl_texture_cube(
|
||||
std::uint32_t texture_id,
|
||||
OpenGlTexture2DBindDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status update_opengl_texture_2d(
|
||||
OpenGlTexture2DUpdate update,
|
||||
OpenGlTexture2DUpdateDispatch dispatch) noexcept;
|
||||
@@ -457,6 +504,22 @@ struct OpenGlFramebufferRestoreDispatch {
|
||||
[[nodiscard]] pp::foundation::Status restore_opengl_framebuffer_binding(
|
||||
OpenGlFramebufferBindingState binding,
|
||||
OpenGlFramebufferRestoreDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<std::uint32_t> create_opengl_sampler(
|
||||
std::span<const OpenGlTextureParameter> parameters,
|
||||
OpenGlSamplerCreateDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status set_opengl_sampler_parameters(
|
||||
std::uint32_t sampler_id,
|
||||
std::span<const OpenGlTextureParameter> parameters,
|
||||
OpenGlSamplerParameterDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status set_opengl_sampler_border_color(
|
||||
std::uint32_t sampler_id,
|
||||
std::uint32_t parameter,
|
||||
const float* rgba,
|
||||
OpenGlSamplerBorderDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status bind_opengl_sampler_object(
|
||||
std::uint32_t unit,
|
||||
std::uint32_t sampler_id,
|
||||
OpenGlSamplerBindDispatch dispatch) noexcept;
|
||||
|
||||
[[nodiscard]] std::uint32_t extension_count_query() noexcept;
|
||||
[[nodiscard]] std::uint32_t extension_string_name() noexcept;
|
||||
|
||||
207
src/texture.cpp
207
src/texture.cpp
@@ -9,11 +9,6 @@
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] GLenum texture_cube_map_target() noexcept
|
||||
{
|
||||
return static_cast<GLenum>(pp::renderer::gl::texture_cube_map_target());
|
||||
}
|
||||
|
||||
void gen_opengl_textures(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||
{
|
||||
glGenTextures(static_cast<GLsizei>(count), reinterpret_cast<GLuint*>(ids));
|
||||
@@ -139,6 +134,61 @@ void read_opengl_pixels(
|
||||
pixels);
|
||||
}
|
||||
|
||||
void gen_opengl_samplers(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glGenSamplers(static_cast<GLsizei>(count), reinterpret_cast<GLuint*>(ids));
|
||||
#else
|
||||
for (std::uint32_t i = 0U; i < count; ++i) {
|
||||
ids[i] = 0U;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_opengl_sampler_parameter_i(
|
||||
std::uint32_t sampler,
|
||||
std::uint32_t parameter,
|
||||
std::int32_t value) noexcept
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glSamplerParameteri(
|
||||
static_cast<GLuint>(sampler),
|
||||
static_cast<GLenum>(parameter),
|
||||
static_cast<GLint>(value));
|
||||
#else
|
||||
(void)sampler;
|
||||
(void)parameter;
|
||||
(void)value;
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_opengl_sampler_parameter_fv(
|
||||
std::uint32_t sampler,
|
||||
std::uint32_t parameter,
|
||||
const float* values) noexcept
|
||||
{
|
||||
#if USE_SAMPLER && !defined(__GLES__)
|
||||
glSamplerParameterfv(
|
||||
static_cast<GLuint>(sampler),
|
||||
static_cast<GLenum>(parameter),
|
||||
values);
|
||||
#else
|
||||
(void)sampler;
|
||||
(void)parameter;
|
||||
(void)values;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bind_opengl_sampler(std::uint32_t unit, std::uint32_t sampler) noexcept
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glBindSampler(static_cast<GLuint>(unit), static_cast<GLuint>(sampler));
|
||||
#else
|
||||
(void)unit;
|
||||
(void)sampler;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::map<uint16_t, Texture2D> TextureManager::m_textures;
|
||||
@@ -176,27 +226,25 @@ bool TextureCube::create(int resolution) noexcept
|
||||
{
|
||||
destroy();
|
||||
m_resolution = resolution;
|
||||
glGenTextures(1, &m_cubetex_id);
|
||||
|
||||
if (!m_cubetex_id)
|
||||
return;
|
||||
|
||||
glBindTexture(texture_cube_map_target(), m_cubetex_id);
|
||||
const auto format = pp::renderer::gl::texture_format_for_channel_count(4U);
|
||||
const auto component_type = static_cast<GLenum>(pp::renderer::gl::unsigned_byte_component_type());
|
||||
for (GLuint i = 0; i < 6; i++)
|
||||
const auto texture = pp::renderer::gl::allocate_opengl_texture_cube(
|
||||
pp::renderer::gl::OpenGlTextureCubeAllocation {
|
||||
.resolution = m_resolution,
|
||||
.internal_format = static_cast<std::int32_t>(format.internal_format),
|
||||
.pixel_format = format.pixel_format,
|
||||
.component_type = pp::renderer::gl::unsigned_byte_component_type(),
|
||||
},
|
||||
pp::renderer::gl::OpenGlTextureCubeAllocationDispatch {
|
||||
.gen_textures = gen_opengl_textures,
|
||||
.bind_texture = bind_opengl_texture,
|
||||
.tex_image_2d = upload_opengl_texture_2d,
|
||||
});
|
||||
if (!texture.ok())
|
||||
{
|
||||
glTexImage2D(
|
||||
static_cast<GLenum>(pp::renderer::gl::cube_map_allocation_face_texture_target(i)),
|
||||
0,
|
||||
static_cast<GLint>(format.internal_format),
|
||||
m_resolution,
|
||||
m_resolution,
|
||||
0,
|
||||
static_cast<GLenum>(format.pixel_format),
|
||||
component_type,
|
||||
nullptr);
|
||||
LOG("TextureCube::create() failed because: %s", texture.status().message);
|
||||
return;
|
||||
}
|
||||
m_cubetex_id = static_cast<GLuint>(texture.value());
|
||||
});
|
||||
return m_cubetex_id != 0;
|
||||
}
|
||||
@@ -207,8 +255,17 @@ void TextureCube::destroy() noexcept
|
||||
{
|
||||
App::I->render_task([f=m_faces, id=m_cubetex_id]
|
||||
{
|
||||
glDeleteTextures(static_cast<GLsizei>(f.size()), f.data());
|
||||
glDeleteTextures(1, &id);
|
||||
std::array<std::uint32_t, 7> texture_ids {};
|
||||
for (std::size_t i = 0U; i < f.size(); ++i)
|
||||
texture_ids[i] = static_cast<std::uint32_t>(f[i]);
|
||||
texture_ids[f.size()] = static_cast<std::uint32_t>(id);
|
||||
const auto status = pp::renderer::gl::delete_opengl_texture_objects(
|
||||
texture_ids,
|
||||
pp::renderer::gl::OpenGlTexture2DDeleteDispatch {
|
||||
.delete_textures = delete_opengl_textures,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("TextureCube::destroy() failed because: %s", status.message);
|
||||
});
|
||||
m_cubetex_id = 0;
|
||||
m_faces.fill(0);
|
||||
@@ -219,7 +276,13 @@ void TextureCube::destroy() noexcept
|
||||
void TextureCube::bind() const noexcept
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
glBindTexture(texture_cube_map_target(), m_cubetex_id);
|
||||
const auto status = pp::renderer::gl::bind_opengl_texture_cube(
|
||||
static_cast<std::uint32_t>(m_cubetex_id),
|
||||
pp::renderer::gl::OpenGlTexture2DBindDispatch {
|
||||
.bind_texture = bind_opengl_texture,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("TextureCube::bind() failed because: %s", status.message);
|
||||
}
|
||||
|
||||
bool TextureManager::load(const char* path, bool generate_mipmaps)
|
||||
@@ -525,15 +588,22 @@ bool Sampler::create(GLint filter, GLint wrap)
|
||||
bool ret = false;
|
||||
App::I->render_task([this, &ret, filter, wrap]
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glGenSamplers(1, &id);
|
||||
#endif // USE_SAMPLER
|
||||
if (id == 0)
|
||||
const auto parameters = pp::renderer::gl::sampler_parameters_for_filter_wrap(
|
||||
static_cast<std::uint32_t>(filter),
|
||||
static_cast<std::uint32_t>(wrap));
|
||||
const auto sampler = pp::renderer::gl::create_opengl_sampler(
|
||||
parameters,
|
||||
pp::renderer::gl::OpenGlSamplerCreateDispatch {
|
||||
.gen_samplers = gen_opengl_samplers,
|
||||
.sampler_parameter_i = set_opengl_sampler_parameter_i,
|
||||
});
|
||||
if (!sampler.ok())
|
||||
{
|
||||
ret = false;
|
||||
LOG("Sampler::create() failed because: %s", sampler.status().message);
|
||||
return;
|
||||
}
|
||||
set(filter, wrap);
|
||||
id = static_cast<GLuint>(sampler.value());
|
||||
ret = true;
|
||||
});
|
||||
return ret;
|
||||
@@ -555,14 +625,17 @@ void Sampler::set(GLint filter, GLint wrap)
|
||||
{
|
||||
App::I->render_task([=]
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
for (const auto parameter : pp::renderer::gl::sampler_parameters_for_filter_wrap(
|
||||
static_cast<std::uint32_t>(filter),
|
||||
static_cast<std::uint32_t>(wrap)))
|
||||
{
|
||||
glSamplerParameteri(id, static_cast<GLenum>(parameter.name), static_cast<GLint>(parameter.value));
|
||||
}
|
||||
#endif // USE_SAMPLER
|
||||
const auto parameters = pp::renderer::gl::sampler_parameters_for_filter_wrap(
|
||||
static_cast<std::uint32_t>(filter),
|
||||
static_cast<std::uint32_t>(wrap));
|
||||
const auto status = pp::renderer::gl::set_opengl_sampler_parameters(
|
||||
static_cast<std::uint32_t>(id),
|
||||
parameters,
|
||||
pp::renderer::gl::OpenGlSamplerParameterDispatch {
|
||||
.sampler_parameter_i = set_opengl_sampler_parameter_i,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("Sampler::set() failed because: %s", status.message);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -582,41 +655,57 @@ void Sampler::set_filter(GLint filter_min, GLint filter_mag)
|
||||
{
|
||||
App::I->render_task([=]
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
for (const auto parameter : pp::renderer::gl::sampler_filter_parameters(
|
||||
static_cast<std::uint32_t>(filter_min),
|
||||
static_cast<std::uint32_t>(filter_mag)))
|
||||
{
|
||||
glSamplerParameteri(id, static_cast<GLenum>(parameter.name), static_cast<GLint>(parameter.value));
|
||||
}
|
||||
#endif // USE_SAMPLER
|
||||
const auto parameters = pp::renderer::gl::sampler_filter_parameters(
|
||||
static_cast<std::uint32_t>(filter_min),
|
||||
static_cast<std::uint32_t>(filter_mag));
|
||||
const auto status = pp::renderer::gl::set_opengl_sampler_parameters(
|
||||
static_cast<std::uint32_t>(id),
|
||||
parameters,
|
||||
pp::renderer::gl::OpenGlSamplerParameterDispatch {
|
||||
.sampler_parameter_i = set_opengl_sampler_parameter_i,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("Sampler::set_filter() failed because: %s", status.message);
|
||||
});
|
||||
}
|
||||
void Sampler::set_border(glm::vec4 rgba)
|
||||
{
|
||||
App::I->render_task([this, rgba]
|
||||
{
|
||||
#if USE_SAMPLER && !defined(__GLES__)
|
||||
glSamplerParameterfv(
|
||||
id,
|
||||
static_cast<GLenum>(pp::renderer::gl::sampler_border_color_parameter_name()),
|
||||
glm::value_ptr(rgba));
|
||||
#endif // USE_SAMPLER
|
||||
const auto status = pp::renderer::gl::set_opengl_sampler_border_color(
|
||||
static_cast<std::uint32_t>(id),
|
||||
pp::renderer::gl::sampler_border_color_parameter_name(),
|
||||
glm::value_ptr(rgba),
|
||||
pp::renderer::gl::OpenGlSamplerBorderDispatch {
|
||||
.sampler_parameter_fv = set_opengl_sampler_parameter_fv,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("Sampler::set_border() failed because: %s", status.message);
|
||||
});
|
||||
}
|
||||
void Sampler::bind(int unit) const
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
current_unit = unit;
|
||||
#if USE_SAMPLER
|
||||
glBindSampler(unit, id);
|
||||
#endif // USE_SAMPLER
|
||||
const auto status = pp::renderer::gl::bind_opengl_sampler_object(
|
||||
static_cast<std::uint32_t>(unit),
|
||||
static_cast<std::uint32_t>(id),
|
||||
pp::renderer::gl::OpenGlSamplerBindDispatch {
|
||||
.bind_sampler = bind_opengl_sampler,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("Sampler::bind() failed because: %s", status.message);
|
||||
}
|
||||
void Sampler::unbind()
|
||||
{
|
||||
assert(App::I->is_render_thread());
|
||||
#if USE_SAMPLER
|
||||
glBindSampler(current_unit, 0);
|
||||
#endif // USE_SAMPLER
|
||||
const auto status = pp::renderer::gl::bind_opengl_sampler_object(
|
||||
static_cast<std::uint32_t>(current_unit),
|
||||
0U,
|
||||
pp::renderer::gl::OpenGlSamplerBindDispatch {
|
||||
.bind_sampler = bind_opengl_sampler,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("Sampler::unbind() failed because: %s", status.message);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,18 @@ struct RecordedOpenGlBlitFramebufferCall {
|
||||
std::uint32_t filter = 0;
|
||||
};
|
||||
|
||||
struct RecordedOpenGlSamplerParameterCall {
|
||||
std::uint32_t sampler = 0;
|
||||
std::uint32_t parameter = 0;
|
||||
std::int32_t value = 0;
|
||||
};
|
||||
|
||||
struct RecordedOpenGlSamplerBorderCall {
|
||||
std::uint32_t sampler = 0;
|
||||
std::uint32_t parameter = 0;
|
||||
const float* values = nullptr;
|
||||
};
|
||||
|
||||
std::vector<RecordedOpenGlStateCall> recorded_state_calls;
|
||||
std::vector<std::uint32_t> recorded_string_queries;
|
||||
std::vector<pp::renderer::gl::OpenGlDefaultClear> recorded_clear_calls;
|
||||
@@ -103,8 +115,12 @@ std::vector<RecordedOpenGlFramebufferAttachmentCall> recorded_framebuffer_attach
|
||||
std::vector<std::uint32_t> recorded_framebuffer_status_queries;
|
||||
std::vector<RecordedOpenGlReadPixelsCall> recorded_read_pixels_calls;
|
||||
std::vector<RecordedOpenGlBlitFramebufferCall> recorded_blit_framebuffer_calls;
|
||||
std::vector<std::uint32_t> recorded_generated_sampler_counts;
|
||||
std::vector<RecordedOpenGlSamplerParameterCall> recorded_sampler_parameter_calls;
|
||||
std::vector<RecordedOpenGlSamplerBorderCall> recorded_sampler_border_calls;
|
||||
std::uint32_t next_texture_id = 91U;
|
||||
std::uint32_t next_framebuffer_id = 44U;
|
||||
std::uint32_t next_sampler_id = 71U;
|
||||
std::uint32_t configured_framebuffer_status = 0x8CD5U;
|
||||
|
||||
void record_enable(std::uint32_t state) noexcept
|
||||
@@ -447,6 +463,38 @@ void record_blit_framebuffer(
|
||||
});
|
||||
}
|
||||
|
||||
void record_gen_samplers(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||
{
|
||||
recorded_generated_sampler_counts.push_back(count);
|
||||
for (std::uint32_t i = 0U; i < count; ++i) {
|
||||
ids[i] = next_sampler_id + i;
|
||||
}
|
||||
}
|
||||
|
||||
void record_sampler_parameter_i(
|
||||
std::uint32_t sampler,
|
||||
std::uint32_t parameter,
|
||||
std::int32_t value) noexcept
|
||||
{
|
||||
recorded_sampler_parameter_calls.push_back(RecordedOpenGlSamplerParameterCall {
|
||||
.sampler = sampler,
|
||||
.parameter = parameter,
|
||||
.value = value,
|
||||
});
|
||||
}
|
||||
|
||||
void record_sampler_parameter_fv(
|
||||
std::uint32_t sampler,
|
||||
std::uint32_t parameter,
|
||||
const float* values) noexcept
|
||||
{
|
||||
recorded_sampler_border_calls.push_back(RecordedOpenGlSamplerBorderCall {
|
||||
.sampler = sampler,
|
||||
.parameter = parameter,
|
||||
.values = values,
|
||||
});
|
||||
}
|
||||
|
||||
void detects_common_extension_capabilities(pp::tests::Harness& h)
|
||||
{
|
||||
constexpr std::array<std::string_view, 2> extensions {
|
||||
@@ -1626,6 +1674,276 @@ void deletes_and_binds_texture_2d_through_dispatch(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, recorded_binding_calls[0].second == 27U);
|
||||
}
|
||||
|
||||
void deletes_texture_objects_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_deleted_textures.clear();
|
||||
|
||||
constexpr std::array<std::uint32_t, 3> textures { 0U, 7U, 11U };
|
||||
const auto status = pp::renderer::gl::delete_opengl_texture_objects(
|
||||
textures,
|
||||
pp::renderer::gl::OpenGlTexture2DDeleteDispatch {
|
||||
.delete_textures = record_delete_textures,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, status.ok());
|
||||
PP_EXPECT(h, recorded_deleted_textures.size() == 3U);
|
||||
PP_EXPECT(h, recorded_deleted_textures[0] == 0U);
|
||||
PP_EXPECT(h, recorded_deleted_textures[1] == 7U);
|
||||
PP_EXPECT(h, recorded_deleted_textures[2] == 11U);
|
||||
}
|
||||
|
||||
void allocates_texture_cube_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_generated_texture_counts.clear();
|
||||
recorded_binding_calls.clear();
|
||||
recorded_texture_image_calls.clear();
|
||||
next_texture_id = 121U;
|
||||
|
||||
const auto texture = pp::renderer::gl::allocate_opengl_texture_cube(
|
||||
pp::renderer::gl::OpenGlTextureCubeAllocation {
|
||||
.resolution = 64,
|
||||
.internal_format = 0x8058,
|
||||
.pixel_format = 0x1908U,
|
||||
.component_type = 0x1401U,
|
||||
},
|
||||
pp::renderer::gl::OpenGlTextureCubeAllocationDispatch {
|
||||
.gen_textures = record_gen_textures,
|
||||
.bind_texture = record_bind_texture,
|
||||
.tex_image_2d = record_tex_image_2d,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, texture.ok());
|
||||
PP_EXPECT(h, texture.value() == 121U);
|
||||
PP_EXPECT(h, recorded_generated_texture_counts.size() == 1U);
|
||||
PP_EXPECT(h, recorded_generated_texture_counts[0] == 1U);
|
||||
PP_EXPECT(h, recorded_binding_calls.size() == 1U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].kind == RecordedOpenGlBindingCall::Kind::bind_texture);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].first == 0x8513U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].second == 121U);
|
||||
PP_EXPECT(h, recorded_texture_image_calls.size() == 6U);
|
||||
for (std::size_t i = 0U; i < recorded_texture_image_calls.size(); ++i) {
|
||||
PP_EXPECT(h, recorded_texture_image_calls[i].target == 0x8515U + static_cast<std::uint32_t>(i));
|
||||
PP_EXPECT(h, recorded_texture_image_calls[i].width == 64);
|
||||
PP_EXPECT(h, recorded_texture_image_calls[i].height == 64);
|
||||
PP_EXPECT(h, recorded_texture_image_calls[i].internal_format == 0x8058);
|
||||
PP_EXPECT(h, recorded_texture_image_calls[i].pixel_format == 0x1908U);
|
||||
PP_EXPECT(h, recorded_texture_image_calls[i].component_type == 0x1401U);
|
||||
PP_EXPECT(h, recorded_texture_image_calls[i].data == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void rejects_invalid_texture_cube_allocation(pp::tests::Harness& h)
|
||||
{
|
||||
const auto missing_dispatch = pp::renderer::gl::allocate_opengl_texture_cube(
|
||||
pp::renderer::gl::OpenGlTextureCubeAllocation {
|
||||
.resolution = 1,
|
||||
.internal_format = 0x8058,
|
||||
.pixel_format = 0x1908U,
|
||||
.component_type = 0x1401U,
|
||||
},
|
||||
pp::renderer::gl::OpenGlTextureCubeAllocationDispatch {
|
||||
.gen_textures = record_gen_textures,
|
||||
.bind_texture = record_bind_texture,
|
||||
});
|
||||
const auto invalid_resolution = pp::renderer::gl::allocate_opengl_texture_cube(
|
||||
pp::renderer::gl::OpenGlTextureCubeAllocation {
|
||||
.resolution = 0,
|
||||
.internal_format = 0x8058,
|
||||
.pixel_format = 0x1908U,
|
||||
.component_type = 0x1401U,
|
||||
},
|
||||
pp::renderer::gl::OpenGlTextureCubeAllocationDispatch {
|
||||
.gen_textures = record_gen_textures,
|
||||
.bind_texture = record_bind_texture,
|
||||
.tex_image_2d = record_tex_image_2d,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, !missing_dispatch.ok());
|
||||
PP_EXPECT(h, missing_dispatch.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !invalid_resolution.ok());
|
||||
PP_EXPECT(h, invalid_resolution.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void binds_texture_cube_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_binding_calls.clear();
|
||||
|
||||
const auto status = pp::renderer::gl::bind_opengl_texture_cube(
|
||||
33U,
|
||||
pp::renderer::gl::OpenGlTexture2DBindDispatch {
|
||||
.bind_texture = record_bind_texture,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, status.ok());
|
||||
PP_EXPECT(h, recorded_binding_calls.size() == 1U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].kind == RecordedOpenGlBindingCall::Kind::bind_texture);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].first == 0x8513U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].second == 33U);
|
||||
}
|
||||
|
||||
void creates_sampler_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_generated_sampler_counts.clear();
|
||||
recorded_sampler_parameter_calls.clear();
|
||||
next_sampler_id = 81U;
|
||||
const auto parameters = pp::renderer::gl::sampler_parameters_for_filter_wrap(0x2601U, 0x812FU);
|
||||
|
||||
const auto sampler = pp::renderer::gl::create_opengl_sampler(
|
||||
parameters,
|
||||
pp::renderer::gl::OpenGlSamplerCreateDispatch {
|
||||
.gen_samplers = record_gen_samplers,
|
||||
.sampler_parameter_i = record_sampler_parameter_i,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, sampler.ok());
|
||||
PP_EXPECT(h, sampler.value() == 81U);
|
||||
PP_EXPECT(h, recorded_generated_sampler_counts.size() == 1U);
|
||||
PP_EXPECT(h, recorded_generated_sampler_counts[0] == 1U);
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls.size() == parameters.size());
|
||||
for (std::size_t i = 0U; i < parameters.size(); ++i) {
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls[i].sampler == 81U);
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls[i].parameter == parameters[i].name);
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls[i].value == static_cast<std::int32_t>(parameters[i].value));
|
||||
}
|
||||
}
|
||||
|
||||
void sets_sampler_parameters_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_sampler_parameter_calls.clear();
|
||||
const auto parameters = pp::renderer::gl::sampler_filter_parameters(0x2600U, 0x2601U);
|
||||
|
||||
const auto status = pp::renderer::gl::set_opengl_sampler_parameters(
|
||||
17U,
|
||||
parameters,
|
||||
pp::renderer::gl::OpenGlSamplerParameterDispatch {
|
||||
.sampler_parameter_i = record_sampler_parameter_i,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, status.ok());
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls.size() == 2U);
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls[0].sampler == 17U);
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls[0].parameter == 0x2801U);
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls[0].value == 0x2600);
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls[1].parameter == 0x2800U);
|
||||
PP_EXPECT(h, recorded_sampler_parameter_calls[1].value == 0x2601);
|
||||
}
|
||||
|
||||
void sets_sampler_border_color_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_sampler_border_calls.clear();
|
||||
constexpr std::array<float, 4> rgba { 0.25F, 0.5F, 0.75F, 1.0F };
|
||||
|
||||
const auto status = pp::renderer::gl::set_opengl_sampler_border_color(
|
||||
19U,
|
||||
0x1004U,
|
||||
rgba.data(),
|
||||
pp::renderer::gl::OpenGlSamplerBorderDispatch {
|
||||
.sampler_parameter_fv = record_sampler_parameter_fv,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, status.ok());
|
||||
PP_EXPECT(h, recorded_sampler_border_calls.size() == 1U);
|
||||
PP_EXPECT(h, recorded_sampler_border_calls[0].sampler == 19U);
|
||||
PP_EXPECT(h, recorded_sampler_border_calls[0].parameter == 0x1004U);
|
||||
PP_EXPECT(h, recorded_sampler_border_calls[0].values == rgba.data());
|
||||
}
|
||||
|
||||
void binds_sampler_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_binding_calls.clear();
|
||||
|
||||
const auto bind_status = pp::renderer::gl::bind_opengl_sampler_object(
|
||||
3U,
|
||||
23U,
|
||||
pp::renderer::gl::OpenGlSamplerBindDispatch {
|
||||
.bind_sampler = record_bind_sampler,
|
||||
});
|
||||
const auto unbind_status = pp::renderer::gl::bind_opengl_sampler_object(
|
||||
3U,
|
||||
0U,
|
||||
pp::renderer::gl::OpenGlSamplerBindDispatch {
|
||||
.bind_sampler = record_bind_sampler,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, bind_status.ok());
|
||||
PP_EXPECT(h, unbind_status.ok());
|
||||
PP_EXPECT(h, recorded_binding_calls.size() == 2U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].kind == RecordedOpenGlBindingCall::Kind::bind_sampler);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].first == 3U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].second == 23U);
|
||||
PP_EXPECT(h, recorded_binding_calls[1].kind == RecordedOpenGlBindingCall::Kind::bind_sampler);
|
||||
PP_EXPECT(h, recorded_binding_calls[1].first == 3U);
|
||||
PP_EXPECT(h, recorded_binding_calls[1].second == 0U);
|
||||
}
|
||||
|
||||
void rejects_invalid_sampler_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
constexpr std::array<pp::renderer::gl::OpenGlTextureParameter, 1> parameters {
|
||||
pp::renderer::gl::OpenGlTextureParameter { .name = 0x2801U, .value = 0x2601U },
|
||||
};
|
||||
constexpr std::array<pp::renderer::gl::OpenGlTextureParameter, 1> invalid_parameters {
|
||||
pp::renderer::gl::OpenGlTextureParameter { .name = 0U, .value = 0x2601U },
|
||||
};
|
||||
constexpr std::array<float, 4> rgba { 1.0F, 1.0F, 1.0F, 1.0F };
|
||||
|
||||
const auto missing_create_dispatch = pp::renderer::gl::create_opengl_sampler(
|
||||
parameters,
|
||||
pp::renderer::gl::OpenGlSamplerCreateDispatch {
|
||||
.gen_samplers = record_gen_samplers,
|
||||
});
|
||||
const auto empty_create_parameters = pp::renderer::gl::create_opengl_sampler(
|
||||
{},
|
||||
pp::renderer::gl::OpenGlSamplerCreateDispatch {
|
||||
.gen_samplers = record_gen_samplers,
|
||||
.sampler_parameter_i = record_sampler_parameter_i,
|
||||
});
|
||||
const auto zero_sampler_parameters = pp::renderer::gl::set_opengl_sampler_parameters(
|
||||
0U,
|
||||
parameters,
|
||||
pp::renderer::gl::OpenGlSamplerParameterDispatch {
|
||||
.sampler_parameter_i = record_sampler_parameter_i,
|
||||
});
|
||||
const auto invalid_parameter_name = pp::renderer::gl::set_opengl_sampler_parameters(
|
||||
7U,
|
||||
invalid_parameters,
|
||||
pp::renderer::gl::OpenGlSamplerParameterDispatch {
|
||||
.sampler_parameter_i = record_sampler_parameter_i,
|
||||
});
|
||||
const auto null_border = pp::renderer::gl::set_opengl_sampler_border_color(
|
||||
7U,
|
||||
0x1004U,
|
||||
nullptr,
|
||||
pp::renderer::gl::OpenGlSamplerBorderDispatch {
|
||||
.sampler_parameter_fv = record_sampler_parameter_fv,
|
||||
});
|
||||
const auto zero_border_parameter = pp::renderer::gl::set_opengl_sampler_border_color(
|
||||
7U,
|
||||
0U,
|
||||
rgba.data(),
|
||||
pp::renderer::gl::OpenGlSamplerBorderDispatch {
|
||||
.sampler_parameter_fv = record_sampler_parameter_fv,
|
||||
});
|
||||
const auto missing_bind_dispatch = pp::renderer::gl::bind_opengl_sampler_object(
|
||||
0U,
|
||||
7U,
|
||||
pp::renderer::gl::OpenGlSamplerBindDispatch {});
|
||||
|
||||
PP_EXPECT(h, !missing_create_dispatch.ok());
|
||||
PP_EXPECT(h, missing_create_dispatch.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !empty_create_parameters.ok());
|
||||
PP_EXPECT(h, empty_create_parameters.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !zero_sampler_parameters.ok());
|
||||
PP_EXPECT(h, zero_sampler_parameters.code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !invalid_parameter_name.ok());
|
||||
PP_EXPECT(h, invalid_parameter_name.code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !null_border.ok());
|
||||
PP_EXPECT(h, null_border.code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !zero_border_parameter.ok());
|
||||
PP_EXPECT(h, zero_border_parameter.code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !missing_bind_dispatch.ok());
|
||||
PP_EXPECT(h, missing_bind_dispatch.code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void updates_texture_2d_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_binding_calls.clear();
|
||||
@@ -2399,6 +2717,15 @@ int main()
|
||||
harness.run("allocates_texture_2d_through_dispatch", allocates_texture_2d_through_dispatch);
|
||||
harness.run("rejects_invalid_texture_2d_allocation", rejects_invalid_texture_2d_allocation);
|
||||
harness.run("deletes_and_binds_texture_2d_through_dispatch", deletes_and_binds_texture_2d_through_dispatch);
|
||||
harness.run("deletes_texture_objects_through_dispatch", deletes_texture_objects_through_dispatch);
|
||||
harness.run("allocates_texture_cube_through_dispatch", allocates_texture_cube_through_dispatch);
|
||||
harness.run("rejects_invalid_texture_cube_allocation", rejects_invalid_texture_cube_allocation);
|
||||
harness.run("binds_texture_cube_through_dispatch", binds_texture_cube_through_dispatch);
|
||||
harness.run("creates_sampler_through_dispatch", creates_sampler_through_dispatch);
|
||||
harness.run("sets_sampler_parameters_through_dispatch", sets_sampler_parameters_through_dispatch);
|
||||
harness.run("sets_sampler_border_color_through_dispatch", sets_sampler_border_color_through_dispatch);
|
||||
harness.run("binds_sampler_through_dispatch", binds_sampler_through_dispatch);
|
||||
harness.run("rejects_invalid_sampler_dispatch", rejects_invalid_sampler_dispatch);
|
||||
harness.run("updates_texture_2d_through_dispatch", updates_texture_2d_through_dispatch);
|
||||
harness.run("generates_texture_2d_mipmaps_through_dispatch", generates_texture_2d_mipmaps_through_dispatch);
|
||||
harness.run("reads_back_texture_2d_through_framebuffer_dispatch", reads_back_texture_2d_through_framebuffer_dispatch);
|
||||
|
||||
Reference in New Issue
Block a user