31 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
32 glEnable(GL_MULTISAMPLE);
36 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
37 glPixelStorei(GL_PACK_ALIGNMENT, 1);
38 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
42 glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
45 glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, line_width_range_);
49 current_mutable_ = ~mutable_state;
57 this->set_state(this->
state);
59 this->texture_bind_apply();
60 this->image_bind_apply();
70 current_ = ~this->state;
72 current_mutable_ = ~this->mutable_state;
73 this->set_state(this->
state);
81 if (changed.
blend != 0) {
116 glEnable(GL_POLYGON_SMOOTH);
119 glDisable(GL_POLYGON_SMOOTH);
124 glEnable(GL_LINE_SMOOTH);
127 glDisable(GL_LINE_SMOOTH);
134void GLStateManager::set_mutable_state(
const GPUStateMutable &
state)
136 GPUStateMutable changed =
state ^ current_mutable_;
140 if (
state.point_size > 0.0f) {
141 glEnable(GL_PROGRAM_POINT_SIZE);
144 glDisable(GL_PROGRAM_POINT_SIZE);
151 glLineWidth(
clamp_f(
state.line_width, line_width_range_[0], line_width_range_[1]));
159 if (changed.stencil_compare_mask != 0 || changed.stencil_reference != 0 ||
160 changed.stencil_write_mask != 0)
165 current_mutable_ =
state;
174void GLStateManager::set_write_mask(
const eGPUWriteMask value)
183 glEnable(GL_RASTERIZER_DISCARD);
186 glDisable(GL_RASTERIZER_DISCARD);
190void GLStateManager::set_depth_test(
const eGPUDepthTest value)
216 glEnable(GL_DEPTH_TEST);
220 glDisable(GL_DEPTH_TEST);
228 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
231 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
232 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
235 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
236 glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
240 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
244 glEnable(GL_STENCIL_TEST);
247 glDisable(GL_STENCIL_TEST);
267 glStencilFunc(GL_ALWAYS, 0x00, 0x00);
271 glStencilMask(
state.stencil_write_mask);
272 glStencilFunc(func,
state.stencil_reference,
state.stencil_compare_mask);
275void GLStateManager::set_clip_distances(
const int new_dist_len,
const int old_dist_len)
277 for (
int i = 0; i < new_dist_len; i++) {
278 glEnable(GL_CLIP_DISTANCE0 + i);
280 for (
int i = new_dist_len; i < old_dist_len; i++) {
281 glDisable(GL_CLIP_DISTANCE0 + i);
285void GLStateManager::set_logic_op(
const bool enable)
288 glEnable(GL_COLOR_LOGIC_OP);
292 glDisable(GL_COLOR_LOGIC_OP);
296void GLStateManager::set_facing(
const bool invert)
298 glFrontFace((
invert) ? GL_CW : GL_CCW);
304 glEnable(GL_CULL_FACE);
308 glDisable(GL_CULL_FACE);
315 GL_LAST_VERTEX_CONVENTION;
316 glProvokingVertex(value);
319void GLStateManager::set_shadow_bias(
const bool enable)
322 glEnable(GL_POLYGON_OFFSET_FILL);
323 glEnable(GL_POLYGON_OFFSET_LINE);
325 glPolygonOffset(2.0f, 1.0f);
328 glDisable(GL_POLYGON_OFFSET_FILL);
329 glDisable(GL_POLYGON_OFFSET_LINE);
333void GLStateManager::set_blend(
const eGPUBlend value)
342 GLenum src_rgb, src_alpha, dst_rgb, dst_alpha;
346 src_rgb = GL_SRC_ALPHA;
347 dst_rgb = GL_ONE_MINUS_SRC_ALPHA;
349 dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
354 dst_rgb = GL_ONE_MINUS_SRC_ALPHA;
356 dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
361 src_rgb = GL_SRC_ALPHA;
377 src_rgb = GL_DST_COLOR;
379 src_alpha = GL_DST_ALPHA;
384 src_rgb = GL_ONE_MINUS_DST_COLOR;
394 dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
398 src_rgb = GL_ONE_MINUS_DST_ALPHA;
399 dst_rgb = GL_SRC_ALPHA;
401 dst_alpha = GL_SRC_ALPHA;
405 src_rgb = GL_ONE_MINUS_DST_ALPHA;
407 src_alpha = GL_ONE_MINUS_DST_ALPHA;
413 dst_rgb = GL_SRC1_COLOR;
415 dst_alpha = GL_SRC1_ALPHA;
421 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
424 glBlendEquation(GL_FUNC_ADD);
430 glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha);
450 tex->check_feedback_loop();
453 if ((textures_[unit] ==
tex->tex_id_) &&
458 targets_[unit] =
tex->target_;
459 textures_[unit] =
tex->tex_id_;
461 tex->is_bound_ =
true;
462 dirty_texture_binds_ |= 1ULL << unit;
467 glActiveTexture(GL_TEXTURE0);
468 glBindTexture(
tex->target_,
tex->tex_id_);
470 dirty_texture_binds_ |= 1ULL;
479 if (!
tex->is_bound_) {
483 GLuint tex_id =
tex->tex_id_;
484 for (
int i = 0; i <
ARRAY_SIZE(textures_); i++) {
485 if (textures_[i] == tex_id) {
488 dirty_texture_binds_ |= 1ULL << i;
491 tex->is_bound_ =
false;
496 for (
int i = 0; i <
ARRAY_SIZE(textures_); i++) {
497 if (textures_[i] != 0) {
500 dirty_texture_binds_ |= 1ULL << i;
503 this->texture_bind_apply();
506void GLStateManager::texture_bind_apply()
508 if (dirty_texture_binds_ == 0) {
511 uint64_t dirty_bind = dirty_texture_binds_;
512 dirty_texture_binds_ = 0;
516 int count = last - first;
519 glBindTextures(first,
count, textures_ + first);
520 glBindSamplers(first,
count, samplers_ + first);
523 for (
int unit = first; unit < last; unit++) {
524 if ((dirty_bind >> unit) & 1UL) {
525 glActiveTexture(GL_TEXTURE0 + unit);
526 glBindTexture(targets_[unit], textures_[unit]);
527 glBindSampler(unit, samplers_[unit]);
535 glPixelStorei(GL_UNPACK_ROW_LENGTH,
len);
541 for (
int i = 0; i <
ARRAY_SIZE(textures_); i++) {
542 if (textures_[i] != 0) {
543 bound_slots |= 1ULL << i;
561 tex->check_feedback_loop();
563 images_[unit] =
tex->tex_id_;
565 tex->is_bound_image_ =
true;
566 dirty_image_binds_ |= 1ULL << unit;
572 if (!
tex->is_bound_image_) {
576 GLuint tex_id =
tex->tex_id_;
577 for (
int i = 0; i <
ARRAY_SIZE(images_); i++) {
578 if (images_[i] == tex_id) {
580 dirty_image_binds_ |= 1ULL << i;
583 tex->is_bound_image_ =
false;
588 for (
int i = 0; i <
ARRAY_SIZE(images_); i++) {
589 if (images_[i] != 0) {
591 dirty_image_binds_ |= 1ULL << i;
594 this->image_bind_apply();
597void GLStateManager::image_bind_apply()
599 if (dirty_image_binds_ == 0) {
602 uint32_t dirty_bind = dirty_image_binds_;
603 dirty_image_binds_ = 0;
607 int count = last - first;
610 glBindImageTextures(first,
count, images_ + first);
613 for (
int unit = first; unit < last; unit++) {
614 if ((dirty_bind >> unit) & 1UL) {
615 glBindImageTexture(unit, images_[unit], 0, GL_TRUE, 0, GL_READ_WRITE, formats_[unit]);
624 for (
int i = 0; i <
ARRAY_SIZE(images_); i++) {
625 if (images_[i] != 0) {
626 bound_slots |= 1ULL << i;
640 glMemoryBarrier(
to_gl(barrier_bits));
645 if (gl_sync_ !=
nullptr) {
646 glDeleteSync(gl_sync_);
655 glDeleteSync(gl_sync_);
658 gl_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
665 if (gl_sync_ ==
nullptr) {
668 glWaitSync(gl_sync_, 0, GL_TIMEOUT_IGNORED);
MINLINE float clamp_f(float value, float min, float max)
MINLINE unsigned int bitscan_forward_uint(unsigned int a)
MINLINE unsigned int float_as_uint(float f)
MINLINE unsigned int bitscan_reverse_uint(unsigned int a)
MINLINE unsigned int bitscan_forward_uint64(unsigned long long a)
MINLINE unsigned int bitscan_reverse_uint64(unsigned long long a)
@ GPU_BLEND_ADDITIVE_PREMULT
@ GPU_BLEND_ALPHA_UNDER_PREMUL
@ GPU_BLEND_ALPHA_PREMULT
@ GPU_STENCIL_OP_COUNT_DEPTH_FAIL
@ GPU_STENCIL_OP_COUNT_DEPTH_PASS
@ GPU_DEPTH_GREATER_EQUAL
static bool multi_bind_support
static bool multi_bind_image_support
void texture_bind_temp(GLTexture *tex)
GLFrameBuffer * active_fb
void image_unbind(Texture *tex) override
void image_bind(Texture *tex, int unit) override
void apply_state() override
void texture_unpack_row_length_set(uint len) override
void issue_barrier(eGPUBarrier barrier_bits) override
void texture_unbind_all() override
uint8_t bound_image_slots()
void force_state() override
uint64_t bound_texture_slots()
void texture_bind(Texture *tex, GPUSamplerState sampler, int unit) override
void image_unbind_all() override
void texture_unbind(Texture *tex) override
static GLuint get_sampler(const GPUSamplerState &sampler_state)
GPUStateMutable mutable_state
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
GLenum to_gl_internal_format(eGPUTextureFormat format)
static GLenum to_gl(const GPUAttachmentType type)
unsigned __int64 uint64_t