Route shader creation through renderer GL
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "renderer_gl/shader_bindings.h"
|
||||
#include "test_harness.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@@ -111,6 +112,29 @@ struct RecordedOpenGlUniformScalarCall {
|
||||
bool is_float = false;
|
||||
};
|
||||
|
||||
struct RecordedOpenGlShaderSourceCall {
|
||||
std::uint32_t shader = 0;
|
||||
std::int32_t count = 0;
|
||||
std::string_view source;
|
||||
};
|
||||
|
||||
struct RecordedOpenGlProgramAttachCall {
|
||||
std::uint32_t program = 0;
|
||||
std::uint32_t shader = 0;
|
||||
};
|
||||
|
||||
struct RecordedOpenGlAttribBindCall {
|
||||
std::uint32_t program = 0;
|
||||
std::uint32_t location = 0;
|
||||
std::string_view name;
|
||||
};
|
||||
|
||||
struct RecordedOpenGlActiveUniformCall {
|
||||
std::uint32_t program = 0;
|
||||
std::uint32_t index = 0;
|
||||
std::int32_t capacity = 0;
|
||||
};
|
||||
|
||||
std::vector<RecordedOpenGlStateCall> recorded_state_calls;
|
||||
std::vector<std::uint32_t> recorded_string_queries;
|
||||
std::vector<pp::renderer::gl::OpenGlDefaultClear> recorded_clear_calls;
|
||||
@@ -138,9 +162,27 @@ std::vector<RecordedOpenGlUniformFloatVectorCall> recorded_uniform_vector_calls;
|
||||
std::vector<RecordedOpenGlUniformScalarCall> recorded_uniform_scalar_calls;
|
||||
std::vector<std::uint32_t> recorded_attrib_location_programs;
|
||||
std::vector<std::string_view> recorded_attrib_location_names;
|
||||
std::vector<std::uint32_t> recorded_created_shader_stages;
|
||||
std::vector<RecordedOpenGlShaderSourceCall> recorded_shader_source_calls;
|
||||
std::vector<std::uint32_t> recorded_compiled_shaders;
|
||||
std::vector<std::uint32_t> recorded_deleted_shaders;
|
||||
std::vector<std::uint32_t> recorded_shader_integer_queries;
|
||||
std::vector<std::uint32_t> recorded_created_programs;
|
||||
std::vector<RecordedOpenGlProgramAttachCall> recorded_program_attach_calls;
|
||||
std::vector<std::uint32_t> recorded_linked_programs;
|
||||
std::vector<RecordedOpenGlAttribBindCall> recorded_attrib_bind_calls;
|
||||
std::vector<std::uint32_t> recorded_program_integer_queries;
|
||||
std::vector<RecordedOpenGlActiveUniformCall> recorded_active_uniform_calls;
|
||||
std::vector<std::uint32_t> recorded_uniform_location_programs;
|
||||
std::vector<std::string_view> recorded_uniform_location_names;
|
||||
std::uint32_t next_texture_id = 91U;
|
||||
std::uint32_t next_framebuffer_id = 44U;
|
||||
std::uint32_t next_sampler_id = 71U;
|
||||
std::uint32_t next_shader_id = 301U;
|
||||
std::uint32_t next_program_id = 401U;
|
||||
std::int32_t configured_shader_compile_status = 1;
|
||||
std::int32_t configured_program_link_status = 1;
|
||||
std::int32_t configured_active_uniform_count = 2;
|
||||
std::uint32_t configured_framebuffer_status = 0x8CD5U;
|
||||
|
||||
void record_enable(std::uint32_t state) noexcept
|
||||
@@ -592,6 +634,164 @@ std::int32_t record_get_attrib_location(std::uint32_t program, const char* name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::uint32_t record_create_shader(std::uint32_t stage) noexcept
|
||||
{
|
||||
recorded_created_shader_stages.push_back(stage);
|
||||
return next_shader_id++;
|
||||
}
|
||||
|
||||
void record_shader_source(std::uint32_t shader, std::int32_t count, const char* const* sources) noexcept
|
||||
{
|
||||
recorded_shader_source_calls.push_back(RecordedOpenGlShaderSourceCall {
|
||||
.shader = shader,
|
||||
.count = count,
|
||||
.source = sources != nullptr && sources[0] != nullptr ? std::string_view { sources[0] } : std::string_view {},
|
||||
});
|
||||
}
|
||||
|
||||
void record_compile_shader(std::uint32_t shader) noexcept
|
||||
{
|
||||
recorded_compiled_shaders.push_back(shader);
|
||||
}
|
||||
|
||||
void record_get_shader_integer(std::uint32_t shader, std::uint32_t query, std::int32_t* value) noexcept
|
||||
{
|
||||
recorded_shader_integer_queries.push_back(query);
|
||||
if (value != nullptr) {
|
||||
*value = configured_shader_compile_status;
|
||||
}
|
||||
(void)shader;
|
||||
}
|
||||
|
||||
void record_get_shader_info_log(
|
||||
std::uint32_t shader,
|
||||
std::int32_t capacity,
|
||||
std::int32_t* length,
|
||||
char* info_log) noexcept
|
||||
{
|
||||
constexpr std::string_view log_text { "shader note" };
|
||||
if (length != nullptr) {
|
||||
*length = static_cast<std::int32_t>(log_text.size());
|
||||
}
|
||||
if (info_log != nullptr && capacity > 0) {
|
||||
const auto copied = std::min<std::int32_t>(capacity - 1, static_cast<std::int32_t>(log_text.size()));
|
||||
std::memcpy(info_log, log_text.data(), static_cast<std::size_t>(copied));
|
||||
info_log[copied] = '\0';
|
||||
}
|
||||
(void)shader;
|
||||
}
|
||||
|
||||
void record_delete_shader(std::uint32_t shader) noexcept
|
||||
{
|
||||
recorded_deleted_shaders.push_back(shader);
|
||||
}
|
||||
|
||||
std::uint32_t record_create_program() noexcept
|
||||
{
|
||||
recorded_created_programs.push_back(next_program_id);
|
||||
return next_program_id++;
|
||||
}
|
||||
|
||||
void record_attach_shader(std::uint32_t program, std::uint32_t shader) noexcept
|
||||
{
|
||||
recorded_program_attach_calls.push_back(RecordedOpenGlProgramAttachCall {
|
||||
.program = program,
|
||||
.shader = shader,
|
||||
});
|
||||
}
|
||||
|
||||
void record_link_program(std::uint32_t program) noexcept
|
||||
{
|
||||
recorded_linked_programs.push_back(program);
|
||||
}
|
||||
|
||||
void record_bind_attrib_location(std::uint32_t program, std::uint32_t location, const char* name) noexcept
|
||||
{
|
||||
recorded_attrib_bind_calls.push_back(RecordedOpenGlAttribBindCall {
|
||||
.program = program,
|
||||
.location = location,
|
||||
.name = name == nullptr ? std::string_view {} : std::string_view { name },
|
||||
});
|
||||
}
|
||||
|
||||
void record_get_program_integer(std::uint32_t program, std::uint32_t query, std::int32_t* value) noexcept
|
||||
{
|
||||
recorded_program_integer_queries.push_back(query);
|
||||
if (value == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (query == 0x8B82U) {
|
||||
*value = configured_program_link_status;
|
||||
} else if (query == 0x8B86U) {
|
||||
*value = configured_active_uniform_count;
|
||||
} else {
|
||||
*value = -1;
|
||||
}
|
||||
(void)program;
|
||||
}
|
||||
|
||||
void record_get_program_info_log(
|
||||
std::uint32_t program,
|
||||
std::int32_t capacity,
|
||||
std::int32_t* length,
|
||||
char* info_log) noexcept
|
||||
{
|
||||
constexpr std::string_view log_text { "program note" };
|
||||
if (length != nullptr) {
|
||||
*length = static_cast<std::int32_t>(log_text.size());
|
||||
}
|
||||
if (info_log != nullptr && capacity > 0) {
|
||||
const auto copied = std::min<std::int32_t>(capacity - 1, static_cast<std::int32_t>(log_text.size()));
|
||||
std::memcpy(info_log, log_text.data(), static_cast<std::size_t>(copied));
|
||||
info_log[copied] = '\0';
|
||||
}
|
||||
(void)program;
|
||||
}
|
||||
|
||||
void record_get_active_uniform(
|
||||
std::uint32_t program,
|
||||
std::uint32_t index,
|
||||
std::int32_t capacity,
|
||||
std::int32_t* length,
|
||||
std::int32_t* size,
|
||||
std::uint32_t* type,
|
||||
char* name) noexcept
|
||||
{
|
||||
recorded_active_uniform_calls.push_back(RecordedOpenGlActiveUniformCall {
|
||||
.program = program,
|
||||
.index = index,
|
||||
.capacity = capacity,
|
||||
});
|
||||
const std::string_view uniform_name = index == 0U ? std::string_view { "mvp" } : std::string_view { "tex" };
|
||||
if (length != nullptr) {
|
||||
*length = static_cast<std::int32_t>(uniform_name.size());
|
||||
}
|
||||
if (size != nullptr) {
|
||||
*size = 1;
|
||||
}
|
||||
if (type != nullptr) {
|
||||
*type = 0x8B5CU;
|
||||
}
|
||||
if (name != nullptr && capacity > 0) {
|
||||
const auto copied = std::min<std::int32_t>(capacity - 1, static_cast<std::int32_t>(uniform_name.size()));
|
||||
std::memcpy(name, uniform_name.data(), static_cast<std::size_t>(copied));
|
||||
name[copied] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
std::int32_t record_get_uniform_location(std::uint32_t program, const char* name) noexcept
|
||||
{
|
||||
recorded_uniform_location_programs.push_back(program);
|
||||
recorded_uniform_location_names.push_back(name == nullptr ? std::string_view {} : std::string_view { name });
|
||||
if (name != nullptr && std::string_view { name } == std::string_view { "mvp" }) {
|
||||
return 4;
|
||||
}
|
||||
if (name != nullptr && std::string_view { name } == std::string_view { "tex" }) {
|
||||
return 7;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void detects_common_extension_capabilities(pp::tests::Harness& h)
|
||||
{
|
||||
constexpr std::array<std::string_view, 2> extensions {
|
||||
@@ -2256,6 +2456,321 @@ void rejects_invalid_program_uniform_dispatch(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, invalid_attrib_name.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void compiles_shader_source_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_created_shader_stages.clear();
|
||||
recorded_shader_source_calls.clear();
|
||||
recorded_compiled_shaders.clear();
|
||||
recorded_shader_integer_queries.clear();
|
||||
next_shader_id = 301U;
|
||||
configured_shader_compile_status = 1;
|
||||
std::array<char, 64> info_log {};
|
||||
|
||||
const auto shader = pp::renderer::gl::compile_opengl_shader_source(
|
||||
0x8B31U,
|
||||
"void main(){}",
|
||||
info_log.data(),
|
||||
static_cast<std::int32_t>(info_log.size()),
|
||||
pp::renderer::gl::OpenGlShaderCompileDispatch {
|
||||
.create_shader = record_create_shader,
|
||||
.shader_source = record_shader_source,
|
||||
.compile_shader = record_compile_shader,
|
||||
.get_shader_integer = record_get_shader_integer,
|
||||
.get_shader_info_log = record_get_shader_info_log,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, shader.ok());
|
||||
PP_EXPECT(h, shader.value().shader_id == 301U);
|
||||
PP_EXPECT(h, shader.value().compile_status == 1);
|
||||
PP_EXPECT(h, shader.value().info_log_length == 11);
|
||||
PP_EXPECT(h, std::string_view { info_log.data() } == std::string_view("shader note"));
|
||||
PP_EXPECT(h, recorded_created_shader_stages.size() == 1U);
|
||||
PP_EXPECT(h, recorded_created_shader_stages[0] == 0x8B31U);
|
||||
PP_EXPECT(h, recorded_shader_source_calls.size() == 1U);
|
||||
PP_EXPECT(h, recorded_shader_source_calls[0].shader == 301U);
|
||||
PP_EXPECT(h, recorded_shader_source_calls[0].count == 1);
|
||||
PP_EXPECT(h, recorded_shader_source_calls[0].source == std::string_view("void main(){}"));
|
||||
PP_EXPECT(h, recorded_compiled_shaders.size() == 1U);
|
||||
PP_EXPECT(h, recorded_compiled_shaders[0] == 301U);
|
||||
PP_EXPECT(h, recorded_shader_integer_queries.size() == 1U);
|
||||
PP_EXPECT(h, recorded_shader_integer_queries[0] == 0x8B81U);
|
||||
}
|
||||
|
||||
void rejects_invalid_shader_compile_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
std::array<char, 16> info_log {};
|
||||
const auto missing_dispatch = pp::renderer::gl::compile_opengl_shader_source(
|
||||
0x8B31U,
|
||||
"void main(){}",
|
||||
info_log.data(),
|
||||
static_cast<std::int32_t>(info_log.size()),
|
||||
pp::renderer::gl::OpenGlShaderCompileDispatch {
|
||||
.create_shader = record_create_shader,
|
||||
.shader_source = record_shader_source,
|
||||
});
|
||||
const auto empty_source = pp::renderer::gl::compile_opengl_shader_source(
|
||||
0x8B31U,
|
||||
"",
|
||||
info_log.data(),
|
||||
static_cast<std::int32_t>(info_log.size()),
|
||||
pp::renderer::gl::OpenGlShaderCompileDispatch {
|
||||
.create_shader = record_create_shader,
|
||||
.shader_source = record_shader_source,
|
||||
.compile_shader = record_compile_shader,
|
||||
.get_shader_integer = record_get_shader_integer,
|
||||
.get_shader_info_log = record_get_shader_info_log,
|
||||
});
|
||||
const auto missing_log = pp::renderer::gl::compile_opengl_shader_source(
|
||||
0x8B31U,
|
||||
"void main(){}",
|
||||
nullptr,
|
||||
static_cast<std::int32_t>(info_log.size()),
|
||||
pp::renderer::gl::OpenGlShaderCompileDispatch {
|
||||
.create_shader = record_create_shader,
|
||||
.shader_source = record_shader_source,
|
||||
.compile_shader = record_compile_shader,
|
||||
.get_shader_integer = record_get_shader_integer,
|
||||
.get_shader_info_log = record_get_shader_info_log,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, !missing_dispatch.ok());
|
||||
PP_EXPECT(h, missing_dispatch.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !empty_source.ok());
|
||||
PP_EXPECT(h, empty_source.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !missing_log.ok());
|
||||
PP_EXPECT(h, missing_log.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void deletes_shader_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_deleted_shaders.clear();
|
||||
|
||||
const auto delete_status = pp::renderer::gl::delete_opengl_shader(
|
||||
31U,
|
||||
pp::renderer::gl::OpenGlShaderDeleteDispatch {
|
||||
.delete_shader = record_delete_shader,
|
||||
});
|
||||
const auto delete_zero_status = pp::renderer::gl::delete_opengl_shader(
|
||||
0U,
|
||||
pp::renderer::gl::OpenGlShaderDeleteDispatch {
|
||||
.delete_shader = record_delete_shader,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, delete_status.ok());
|
||||
PP_EXPECT(h, delete_zero_status.ok());
|
||||
PP_EXPECT(h, recorded_deleted_shaders.size() == 1U);
|
||||
PP_EXPECT(h, recorded_deleted_shaders[0] == 31U);
|
||||
}
|
||||
|
||||
void links_shader_program_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_created_programs.clear();
|
||||
recorded_program_attach_calls.clear();
|
||||
recorded_deleted_shaders.clear();
|
||||
recorded_linked_programs.clear();
|
||||
recorded_attrib_location_programs.clear();
|
||||
recorded_attrib_location_names.clear();
|
||||
recorded_attrib_bind_calls.clear();
|
||||
recorded_program_integer_queries.clear();
|
||||
next_program_id = 401U;
|
||||
configured_program_link_status = 1;
|
||||
std::array<char, 64> info_log {};
|
||||
|
||||
const auto program = pp::renderer::gl::link_opengl_shader_program(
|
||||
101U,
|
||||
103U,
|
||||
pp::renderer::gl::panopainter_shader_attribute_bindings(),
|
||||
info_log.data(),
|
||||
static_cast<std::int32_t>(info_log.size()),
|
||||
pp::renderer::gl::OpenGlProgramLinkDispatch {
|
||||
.create_program = record_create_program,
|
||||
.attach_shader = record_attach_shader,
|
||||
.delete_shader = record_delete_shader,
|
||||
.link_program = record_link_program,
|
||||
.get_attrib_location = record_get_attrib_location,
|
||||
.bind_attrib_location = record_bind_attrib_location,
|
||||
.get_program_integer = record_get_program_integer,
|
||||
.get_program_info_log = record_get_program_info_log,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, program.ok());
|
||||
PP_EXPECT(h, program.value().program_id == 401U);
|
||||
PP_EXPECT(h, program.value().link_status == 1);
|
||||
PP_EXPECT(h, program.value().info_log_length == 12);
|
||||
PP_EXPECT(h, std::string_view { info_log.data() } == std::string_view("program note"));
|
||||
PP_EXPECT(h, recorded_created_programs.size() == 1U);
|
||||
PP_EXPECT(h, recorded_created_programs[0] == 401U);
|
||||
PP_EXPECT(h, recorded_program_attach_calls.size() == 2U);
|
||||
PP_EXPECT(h, recorded_program_attach_calls[0].shader == 101U);
|
||||
PP_EXPECT(h, recorded_program_attach_calls[1].shader == 103U);
|
||||
PP_EXPECT(h, recorded_deleted_shaders.size() == 2U);
|
||||
PP_EXPECT(h, recorded_deleted_shaders[0] == 101U);
|
||||
PP_EXPECT(h, recorded_deleted_shaders[1] == 103U);
|
||||
PP_EXPECT(h, recorded_linked_programs.size() == 2U);
|
||||
PP_EXPECT(h, recorded_linked_programs[0] == 401U);
|
||||
PP_EXPECT(h, recorded_linked_programs[1] == 401U);
|
||||
PP_EXPECT(h, recorded_attrib_bind_calls.size() == 1U);
|
||||
PP_EXPECT(h, recorded_attrib_bind_calls[0].program == 401U);
|
||||
PP_EXPECT(h, recorded_attrib_bind_calls[0].location == 1U);
|
||||
PP_EXPECT(h, recorded_attrib_bind_calls[0].name == std::string_view("uvs"));
|
||||
PP_EXPECT(h, recorded_program_integer_queries.size() == 1U);
|
||||
PP_EXPECT(h, recorded_program_integer_queries[0] == 0x8B82U);
|
||||
}
|
||||
|
||||
void rejects_invalid_shader_program_link_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
std::array<char, 16> info_log {};
|
||||
const auto missing_dispatch = pp::renderer::gl::link_opengl_shader_program(
|
||||
1U,
|
||||
2U,
|
||||
pp::renderer::gl::panopainter_shader_attribute_bindings(),
|
||||
info_log.data(),
|
||||
static_cast<std::int32_t>(info_log.size()),
|
||||
pp::renderer::gl::OpenGlProgramLinkDispatch {
|
||||
.create_program = record_create_program,
|
||||
.attach_shader = record_attach_shader,
|
||||
});
|
||||
const auto zero_shader = pp::renderer::gl::link_opengl_shader_program(
|
||||
0U,
|
||||
2U,
|
||||
pp::renderer::gl::panopainter_shader_attribute_bindings(),
|
||||
info_log.data(),
|
||||
static_cast<std::int32_t>(info_log.size()),
|
||||
pp::renderer::gl::OpenGlProgramLinkDispatch {
|
||||
.create_program = record_create_program,
|
||||
.attach_shader = record_attach_shader,
|
||||
.delete_shader = record_delete_shader,
|
||||
.link_program = record_link_program,
|
||||
.get_attrib_location = record_get_attrib_location,
|
||||
.bind_attrib_location = record_bind_attrib_location,
|
||||
.get_program_integer = record_get_program_integer,
|
||||
.get_program_info_log = record_get_program_info_log,
|
||||
});
|
||||
const auto missing_log = pp::renderer::gl::link_opengl_shader_program(
|
||||
1U,
|
||||
2U,
|
||||
pp::renderer::gl::panopainter_shader_attribute_bindings(),
|
||||
nullptr,
|
||||
static_cast<std::int32_t>(info_log.size()),
|
||||
pp::renderer::gl::OpenGlProgramLinkDispatch {
|
||||
.create_program = record_create_program,
|
||||
.attach_shader = record_attach_shader,
|
||||
.delete_shader = record_delete_shader,
|
||||
.link_program = record_link_program,
|
||||
.get_attrib_location = record_get_attrib_location,
|
||||
.bind_attrib_location = record_bind_attrib_location,
|
||||
.get_program_integer = record_get_program_integer,
|
||||
.get_program_info_log = record_get_program_info_log,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, !missing_dispatch.ok());
|
||||
PP_EXPECT(h, missing_dispatch.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !zero_shader.ok());
|
||||
PP_EXPECT(h, zero_shader.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !missing_log.ok());
|
||||
PP_EXPECT(h, missing_log.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void discovers_program_uniforms_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_program_integer_queries.clear();
|
||||
recorded_active_uniform_calls.clear();
|
||||
recorded_uniform_location_programs.clear();
|
||||
recorded_uniform_location_names.clear();
|
||||
configured_active_uniform_count = 2;
|
||||
std::array<char, 64> name {};
|
||||
|
||||
const auto count = pp::renderer::gl::query_opengl_program_integer(
|
||||
401U,
|
||||
pp::renderer::gl::active_uniform_count_query(),
|
||||
pp::renderer::gl::OpenGlProgramIntegerDispatch {
|
||||
.get_program_integer = record_get_program_integer,
|
||||
});
|
||||
const auto first = pp::renderer::gl::get_opengl_active_uniform(
|
||||
401U,
|
||||
0U,
|
||||
name.data(),
|
||||
static_cast<std::int32_t>(name.size()),
|
||||
pp::renderer::gl::OpenGlActiveUniformDispatch {
|
||||
.get_active_uniform = record_get_active_uniform,
|
||||
});
|
||||
const auto location = pp::renderer::gl::get_opengl_uniform_location(
|
||||
401U,
|
||||
name.data(),
|
||||
pp::renderer::gl::OpenGlUniformLocationDispatch {
|
||||
.get_uniform_location = record_get_uniform_location,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, count.ok());
|
||||
PP_EXPECT(h, count.value() == 2);
|
||||
PP_EXPECT(h, first.ok());
|
||||
PP_EXPECT(h, first.value().length == 3);
|
||||
PP_EXPECT(h, first.value().size == 1);
|
||||
PP_EXPECT(h, first.value().type == 0x8B5CU);
|
||||
PP_EXPECT(h, std::string_view { name.data() } == std::string_view("mvp"));
|
||||
PP_EXPECT(h, location.ok());
|
||||
PP_EXPECT(h, location.value() == 4);
|
||||
PP_EXPECT(h, recorded_program_integer_queries.size() == 1U);
|
||||
PP_EXPECT(h, recorded_program_integer_queries[0] == 0x8B86U);
|
||||
PP_EXPECT(h, recorded_active_uniform_calls.size() == 1U);
|
||||
PP_EXPECT(h, recorded_active_uniform_calls[0].program == 401U);
|
||||
PP_EXPECT(h, recorded_active_uniform_calls[0].index == 0U);
|
||||
PP_EXPECT(h, recorded_uniform_location_names.size() == 1U);
|
||||
PP_EXPECT(h, recorded_uniform_location_names[0] == std::string_view("mvp"));
|
||||
}
|
||||
|
||||
void rejects_invalid_uniform_discovery_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
std::array<char, 16> name {};
|
||||
const auto missing_program_integer = pp::renderer::gl::query_opengl_program_integer(
|
||||
1U,
|
||||
pp::renderer::gl::active_uniform_count_query(),
|
||||
pp::renderer::gl::OpenGlProgramIntegerDispatch {});
|
||||
const auto invalid_program_integer = pp::renderer::gl::query_opengl_program_integer(
|
||||
0U,
|
||||
pp::renderer::gl::active_uniform_count_query(),
|
||||
pp::renderer::gl::OpenGlProgramIntegerDispatch {
|
||||
.get_program_integer = record_get_program_integer,
|
||||
});
|
||||
const auto missing_active = pp::renderer::gl::get_opengl_active_uniform(
|
||||
1U,
|
||||
0U,
|
||||
name.data(),
|
||||
static_cast<std::int32_t>(name.size()),
|
||||
pp::renderer::gl::OpenGlActiveUniformDispatch {});
|
||||
const auto invalid_active_buffer = pp::renderer::gl::get_opengl_active_uniform(
|
||||
1U,
|
||||
0U,
|
||||
nullptr,
|
||||
static_cast<std::int32_t>(name.size()),
|
||||
pp::renderer::gl::OpenGlActiveUniformDispatch {
|
||||
.get_active_uniform = record_get_active_uniform,
|
||||
});
|
||||
const auto missing_uniform_location = pp::renderer::gl::get_opengl_uniform_location(
|
||||
1U,
|
||||
"mvp",
|
||||
pp::renderer::gl::OpenGlUniformLocationDispatch {});
|
||||
const auto invalid_uniform_name = pp::renderer::gl::get_opengl_uniform_location(
|
||||
1U,
|
||||
"",
|
||||
pp::renderer::gl::OpenGlUniformLocationDispatch {
|
||||
.get_uniform_location = record_get_uniform_location,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, !missing_program_integer.ok());
|
||||
PP_EXPECT(h, missing_program_integer.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !invalid_program_integer.ok());
|
||||
PP_EXPECT(h, invalid_program_integer.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !missing_active.ok());
|
||||
PP_EXPECT(h, missing_active.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !invalid_active_buffer.ok());
|
||||
PP_EXPECT(h, invalid_active_buffer.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !missing_uniform_location.ok());
|
||||
PP_EXPECT(h, missing_uniform_location.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !invalid_uniform_name.ok());
|
||||
PP_EXPECT(h, invalid_uniform_name.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void updates_texture_2d_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_binding_calls.clear();
|
||||
@@ -3043,6 +3558,13 @@ int main()
|
||||
harness.run("sets_scalar_uniforms_through_dispatch", sets_scalar_uniforms_through_dispatch);
|
||||
harness.run("queries_attribute_location_through_dispatch", queries_attribute_location_through_dispatch);
|
||||
harness.run("rejects_invalid_program_uniform_dispatch", rejects_invalid_program_uniform_dispatch);
|
||||
harness.run("compiles_shader_source_through_dispatch", compiles_shader_source_through_dispatch);
|
||||
harness.run("rejects_invalid_shader_compile_dispatch", rejects_invalid_shader_compile_dispatch);
|
||||
harness.run("deletes_shader_through_dispatch", deletes_shader_through_dispatch);
|
||||
harness.run("links_shader_program_through_dispatch", links_shader_program_through_dispatch);
|
||||
harness.run("rejects_invalid_shader_program_link_dispatch", rejects_invalid_shader_program_link_dispatch);
|
||||
harness.run("discovers_program_uniforms_through_dispatch", discovers_program_uniforms_through_dispatch);
|
||||
harness.run("rejects_invalid_uniform_discovery_dispatch", rejects_invalid_uniform_discovery_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