void GLVertexBuffer::bind() { assert(GLStateBuffer::isBegun()); assert(m_initialized); glBindBuffer(GLenum(m_bufferType), m_id); }
GLenum ProgramGL::getTransformFeedbackBufferMode() const { UNIMPLEMENTED(); return GLenum(); }
void GLGSRender::clear_surface(u32 arg) { if (skip_frame || !framebuffer_status_valid) return; if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return; if ((arg & 0xf3) == 0) return; GLbitfield mask = 0; rsx::surface_depth_format surface_depth_format = rsx::method_registers.surface_depth_fmt(); if (arg & 0x1) { u32 max_depth_value = get_max_depth_value(surface_depth_format); u32 clear_depth = rsx::method_registers.z_clear_value(surface_depth_format == rsx::surface_depth_format::z24s8); gl_state.depth_mask(GL_TRUE); gl_state.clear_depth(f32(clear_depth) / max_depth_value); mask |= GLenum(gl::buffers::depth); gl::render_target *ds = std::get<1>(m_rtts.m_bound_depth_stencil); if (ds && !ds->cleared()) { ds->set_cleared(); ds->old_contents = nullptr; } } if (surface_depth_format == rsx::surface_depth_format::z24s8 && (arg & 0x2)) { u8 clear_stencil = rsx::method_registers.stencil_clear_value(); gl_state.stencil_mask(rsx::method_registers.stencil_mask()); gl_state.clear_stencil(clear_stencil); mask |= GLenum(gl::buffers::stencil); } if (arg & 0xf0) { u8 clear_a = rsx::method_registers.clear_color_a(); u8 clear_r = rsx::method_registers.clear_color_r(); u8 clear_g = rsx::method_registers.clear_color_g(); u8 clear_b = rsx::method_registers.clear_color_b(); gl_state.color_mask(arg & 0xf0); gl_state.clear_color(clear_r, clear_g, clear_b, clear_a); mask |= GLenum(gl::buffers::color); for (auto &rtt : m_rtts.m_bound_render_targets) { if (std::get<0>(rtt) != 0) { std::get<1>(rtt)->set_cleared(true); std::get<1>(rtt)->old_contents = nullptr; } } } glClear(mask); }
void CubeMapTexture::subImageImplementationDefault(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { bindInternal(); glTexSubImage2D(GLenum(coordinate), level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); }
void CubeMapTexture::subImageImplementationDSAEXT(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { _created = true; glTextureSubImage2DEXT(_id, GLenum(coordinate), level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); }
void CubeMapTexture::getImageImplementationDefault(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, std::size_t, GLvoid* const data) { bindInternal(); glGetTexImage(GLenum(coordinate), level, GLenum(format), GLenum(type), data); }
void CubeMapTexture::getImageImplementationDSAEXT(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, std::size_t, GLvoid* const data) { _created = true; glGetTextureImageEXT(_id, GLenum(coordinate), level, GLenum(format), GLenum(type), data); }
void ShaderEffectSource::updateBackbuffer() { if (!m_sourceItem || !QGLContext::currentContext()) return; // Multisampling is not (for now) supported. QSize size = QSize(m_sourceItem->width(), m_sourceItem->height()); if (!m_textureSize.isEmpty()) size = m_textureSize; if (size.height() > 0 && size.width() > 0) { QGLFramebufferObjectFormat format; format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); format.setInternalTextureFormat(m_format); if (!m_fbo) { m_fbo = new ShaderEffectBuffer(size, format); } else { if (!m_fbo->isValid() || m_fbo->size() != size || m_fbo->format().internalTextureFormat() != GLenum(m_format)) { delete m_fbo; m_fbo = 0; m_fbo = new ShaderEffectBuffer(size, format); } } } // Note that real update for the source content happens in shadereffect.cpp m_dirtyTexture = false; }
Shader::Shader(ShaderType type) { mType = type; mShader = glCreateShader(GLenum(type)); assert(mShader != 0); }
void Renderbuffer::storageImplementationDSA(RenderbufferFormat internalFormat, const Vector2i& size) { glNamedRenderbufferStorageEXT(_id, GLenum(internalFormat), size.x(), size.y()); }
/// Sets the swizzle value for green component TextureSwizzleTuple& SwizzleG(TextureSwizzle mode) { _values[1] = GLint(GLenum(mode)); return *this; }
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector3i& size) { glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); }
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Math::Vector< 1, GLsizei >& size) { glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]); }
JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) { if (IsContextLost()) return JS::NullValue(); MakeContextCurrent(); if (MinCapabilityMode()) { switch(pname) { //////////////////////////// // Single-value params // int case LOCAL_GL_MAX_VERTEX_ATTRIBS: return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_ATTRIBS); case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS: return JS::Int32Value(MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS); case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS: return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS); case LOCAL_GL_MAX_VARYING_VECTORS: return JS::Int32Value(MINVALUE_GL_MAX_VARYING_VECTORS); case LOCAL_GL_MAX_TEXTURE_SIZE: return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_SIZE); case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: return JS::Int32Value(MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE); case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS); case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); case LOCAL_GL_MAX_RENDERBUFFER_SIZE: return JS::Int32Value(MINVALUE_GL_MAX_RENDERBUFFER_SIZE); default: // Return the real value; we're not overriding this one break; } } if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) { if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS) { return JS::Int32Value(mImplMaxColorAttachments); } else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS) { return JS::Int32Value(mImplMaxDrawBuffers); } else if (pname >= LOCAL_GL_DRAW_BUFFER0 && pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mImplMaxDrawBuffers)) { GLint iv = 0; gl->fGetIntegerv(pname, &iv); if (mBoundDrawFramebuffer) return JS::Int32Value(iv); const GLint index = (pname - LOCAL_GL_DRAW_BUFFER0); if (iv == LOCAL_GL_COLOR_ATTACHMENT0 + index) return JS::Int32Value(LOCAL_GL_BACK); return JS::Int32Value(LOCAL_GL_NONE); } } if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) { if (pname == LOCAL_GL_VERTEX_ARRAY_BINDING) { WebGLVertexArray* vao = (mBoundVertexArray != mDefaultVertexArray) ? mBoundVertexArray.get() : nullptr; return WebGLObjectAsJSValue(cx, vao, rv); } } if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) { if (pname == LOCAL_GL_TIMESTAMP_EXT) { GLuint64 iv = 0; gl->fGetInteger64v(pname, (GLint64*) &iv); // TODO: JS doesn't support 64-bit integers. Be lossy and // cast to double (53 bits) return JS::NumberValue(static_cast<double>(iv)); } else if (pname == LOCAL_GL_GPU_DISJOINT_EXT) { // When disjoint isn't supported, leave as false. realGLboolean disjoint = LOCAL_GL_FALSE; if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) { gl->fGetBooleanv(pname, &disjoint); } return JS::BooleanValue(bool(disjoint)); } } // Privileged string params exposed by WEBGL_debug_renderer_info. // The privilege check is done in WebGLContext::IsExtensionSupported. // So here we just have to check that the extension is enabled. if (IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) { switch (pname) { case UNMASKED_VENDOR_WEBGL: case UNMASKED_RENDERER_WEBGL: { const char* overridePref = nullptr; GLenum driverEnum = LOCAL_GL_NONE; switch (pname) { case UNMASKED_RENDERER_WEBGL: overridePref = "webgl.renderer-string-override"; driverEnum = LOCAL_GL_RENDERER; break; case UNMASKED_VENDOR_WEBGL: overridePref = "webgl.vendor-string-override"; driverEnum = LOCAL_GL_VENDOR; break; default: MOZ_CRASH("bad `pname`"); } bool hasRetVal = false; nsAutoString ret; if (overridePref) { nsresult res = Preferences::GetString(overridePref, &ret); if (NS_SUCCEEDED(res) && ret.Length() > 0) hasRetVal = true; } if (!hasRetVal) { const char* chars = reinterpret_cast<const char*>(gl->fGetString(driverEnum)); ret = NS_ConvertASCIItoUTF16(chars); hasRetVal = true; } return StringValue(cx, ret, rv); } } } if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) { if (pname == LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT) { GLint i = 0; gl->fGetIntegerv(pname, &i); return JS::Int32Value(i); } } if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) { if (pname == LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) { GLfloat f = 0.f; gl->fGetFloatv(pname, &f); return JS::NumberValue(f); } } switch (pname) { // // String params // case LOCAL_GL_VENDOR: case LOCAL_GL_RENDERER: return StringValue(cx, "Mozilla", rv); case LOCAL_GL_VERSION: return StringValue(cx, "WebGL 1.0", rv); case LOCAL_GL_SHADING_LANGUAGE_VERSION: return StringValue(cx, "WebGL GLSL ES 1.0", rv); //////////////////////////////// // Single-value params // unsigned int case LOCAL_GL_CULL_FACE_MODE: case LOCAL_GL_FRONT_FACE: case LOCAL_GL_ACTIVE_TEXTURE: case LOCAL_GL_STENCIL_FUNC: case LOCAL_GL_STENCIL_FAIL: case LOCAL_GL_STENCIL_PASS_DEPTH_FAIL: case LOCAL_GL_STENCIL_PASS_DEPTH_PASS: case LOCAL_GL_STENCIL_BACK_FUNC: case LOCAL_GL_STENCIL_BACK_FAIL: case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_FAIL: case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_PASS: case LOCAL_GL_DEPTH_FUNC: case LOCAL_GL_BLEND_SRC_RGB: case LOCAL_GL_BLEND_SRC_ALPHA: case LOCAL_GL_BLEND_DST_RGB: case LOCAL_GL_BLEND_DST_ALPHA: case LOCAL_GL_BLEND_EQUATION_RGB: case LOCAL_GL_BLEND_EQUATION_ALPHA: case LOCAL_GL_GENERATE_MIPMAP_HINT: { GLint i = 0; gl->fGetIntegerv(pname, &i); return JS::NumberValue(uint32_t(i)); } case LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE: { if (mBoundReadFramebuffer) { nsCString fbStatusInfoIgnored; const auto status = mBoundReadFramebuffer->CheckFramebufferStatus(&fbStatusInfoIgnored); if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) { ErrorInvalidOperation("getParameter: Read framebuffer must be" " complete before querying" " IMPLEMENTATION_COLOR_READ_TYPE."); return JS::NullValue(); } } GLint i = 0; if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) { gl->fGetIntegerv(pname, &i); } else { i = LOCAL_GL_UNSIGNED_BYTE; } return JS::NumberValue(uint32_t(i)); } case LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT: { if (mBoundReadFramebuffer) { nsCString fbStatusInfoIgnored; const auto status = mBoundReadFramebuffer->CheckFramebufferStatus(&fbStatusInfoIgnored); if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) { ErrorInvalidOperation("getParameter: Read framebuffer must be" " complete before querying" " IMPLEMENTATION_COLOR_READ_FORMAT."); return JS::NullValue(); } } GLint i = 0; if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) { gl->fGetIntegerv(pname, &i); } else { i = LOCAL_GL_RGBA; } // OpenGL ES 3.0.4 p112 Table 3.2 shows that read format SRGB_ALPHA is // not supported. And if internal format of fbo is SRGB8_ALPHA8, then // IMPLEMENTATION_COLOR_READ_FORMAT is SRGB_ALPHA which is not supported // by ReadPixels. So, just return RGBA here. if (i == LOCAL_GL_SRGB_ALPHA) i = LOCAL_GL_RGBA; return JS::NumberValue(uint32_t(i)); } // int case LOCAL_GL_STENCIL_REF: case LOCAL_GL_STENCIL_BACK_REF: { GLint stencilBits = 0; if (!GetStencilBits(&stencilBits)) return JS::NullValue(); // Assuming stencils have 8 bits const GLint stencilMask = (1 << stencilBits) - 1; GLint refValue = 0; gl->fGetIntegerv(pname, &refValue); return JS::Int32Value(refValue & stencilMask); } case LOCAL_GL_STENCIL_BITS: { GLint stencilBits = 0; GetStencilBits(&stencilBits); return JS::Int32Value(stencilBits); } case LOCAL_GL_STENCIL_CLEAR_VALUE: case LOCAL_GL_UNPACK_ALIGNMENT: case LOCAL_GL_PACK_ALIGNMENT: case LOCAL_GL_SUBPIXEL_BITS: case LOCAL_GL_SAMPLE_BUFFERS: case LOCAL_GL_SAMPLES: case LOCAL_GL_MAX_VERTEX_ATTRIBS: case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: case LOCAL_GL_RED_BITS: case LOCAL_GL_GREEN_BITS: case LOCAL_GL_BLUE_BITS: { GLint i = 0; gl->fGetIntegerv(pname, &i); return JS::Int32Value(i); } case LOCAL_GL_DEPTH_BITS: { GLint i = 0; if (!mNeedsFakeNoDepth) { gl->fGetIntegerv(pname, &i); } return JS::Int32Value(i); } case LOCAL_GL_ALPHA_BITS: { GLint i = 0; if (!mNeedsFakeNoAlpha) { gl->fGetIntegerv(pname, &i); } return JS::Int32Value(i); } case LOCAL_GL_MAX_TEXTURE_SIZE: return JS::Int32Value(mImplMaxTextureSize); case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: return JS::Int32Value(mImplMaxCubeMapTextureSize); case LOCAL_GL_MAX_RENDERBUFFER_SIZE: return JS::Int32Value(mImplMaxRenderbufferSize); case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS: return JS::Int32Value(mGLMaxVertexUniformVectors); case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS: return JS::Int32Value(mGLMaxFragmentUniformVectors); case LOCAL_GL_MAX_VARYING_VECTORS: return JS::Int32Value(mGLMaxVaryingVectors); case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: { uint32_t length = mCompressedTextureFormats.Length(); JSObject* obj = dom::Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements()); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as // javascript integer values. We just return them as doubles and javascript doesn't care. case LOCAL_GL_STENCIL_BACK_VALUE_MASK: return JS::DoubleValue(mStencilValueMaskBack); // pass as FP value to allow large values such as 2^32-1. case LOCAL_GL_STENCIL_BACK_WRITEMASK: return JS::DoubleValue(mStencilWriteMaskBack); case LOCAL_GL_STENCIL_VALUE_MASK: return JS::DoubleValue(mStencilValueMaskFront); case LOCAL_GL_STENCIL_WRITEMASK: return JS::DoubleValue(mStencilWriteMaskFront); // float case LOCAL_GL_DEPTH_CLEAR_VALUE: case LOCAL_GL_LINE_WIDTH: case LOCAL_GL_POLYGON_OFFSET_FACTOR: case LOCAL_GL_POLYGON_OFFSET_UNITS: case LOCAL_GL_SAMPLE_COVERAGE_VALUE: { GLfloat f = 0.f; gl->fGetFloatv(pname, &f); return JS::DoubleValue(f); } // bool case LOCAL_GL_BLEND: case LOCAL_GL_DEPTH_TEST: case LOCAL_GL_STENCIL_TEST: case LOCAL_GL_CULL_FACE: case LOCAL_GL_DITHER: case LOCAL_GL_POLYGON_OFFSET_FILL: case LOCAL_GL_SCISSOR_TEST: case LOCAL_GL_SAMPLE_COVERAGE_INVERT: case LOCAL_GL_DEPTH_WRITEMASK: { realGLboolean b = 0; gl->fGetBooleanv(pname, &b); return JS::BooleanValue(bool(b)); } // bool, WebGL-specific case UNPACK_FLIP_Y_WEBGL: return JS::BooleanValue(mPixelStore_FlipY); case UNPACK_PREMULTIPLY_ALPHA_WEBGL: return JS::BooleanValue(mPixelStore_PremultiplyAlpha); // uint, WebGL-specific case UNPACK_COLORSPACE_CONVERSION_WEBGL: return JS::NumberValue(uint32_t(mPixelStore_ColorspaceConversion)); //////////////////////////////// // Complex values // 2 floats case LOCAL_GL_DEPTH_RANGE: case LOCAL_GL_ALIASED_POINT_SIZE_RANGE: case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: { GLfloat fv[2] = { 0 }; gl->fGetFloatv(pname, fv); JSObject* obj = dom::Float32Array::Create(cx, this, 2, fv); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // 4 floats case LOCAL_GL_COLOR_CLEAR_VALUE: case LOCAL_GL_BLEND_COLOR: { GLfloat fv[4] = { 0 }; gl->fGetFloatv(pname, fv); JSObject* obj = dom::Float32Array::Create(cx, this, 4, fv); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // 2 ints case LOCAL_GL_MAX_VIEWPORT_DIMS: { GLint iv[2] = { 0 }; gl->fGetIntegerv(pname, iv); JSObject* obj = dom::Int32Array::Create(cx, this, 2, iv); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // 4 ints case LOCAL_GL_SCISSOR_BOX: case LOCAL_GL_VIEWPORT: { GLint iv[4] = { 0 }; gl->fGetIntegerv(pname, iv); JSObject* obj = dom::Int32Array::Create(cx, this, 4, iv); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } // 4 bools case LOCAL_GL_COLOR_WRITEMASK: { realGLboolean gl_bv[4] = { 0 }; gl->fGetBooleanv(pname, gl_bv); bool vals[4] = { bool(gl_bv[0]), bool(gl_bv[1]), bool(gl_bv[2]), bool(gl_bv[3]) }; JS::Rooted<JS::Value> arr(cx); if (!dom::ToJSValue(cx, vals, &arr)) { rv = NS_ERROR_OUT_OF_MEMORY; } return arr; } case LOCAL_GL_ARRAY_BUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv); } case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundVertexArray->mElementArrayBuffer.get(), rv); } case LOCAL_GL_RENDERBUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv); } // DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING. case LOCAL_GL_FRAMEBUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundDrawFramebuffer.get(), rv); } case LOCAL_GL_CURRENT_PROGRAM: { return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv); } case LOCAL_GL_TEXTURE_BINDING_2D: { return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(), rv); } case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP: { return WebGLObjectAsJSValue(cx, mBoundCubeMapTextures[mActiveTexture].get(), rv); } default: break; } ErrorInvalidEnumInfo("getParameter: parameter", pname); return JS::NullValue(); }
/** * @glsymbols * @glfunref{ReadBuffer} */ static void ReadBuffer(ColorBuffer buffer) { OGLPLUS_GLFUNC(ReadBuffer)(GLenum(buffer)); OGLPLUS_VERIFY(OGLPLUS_ERROR_INFO(ReadBuffer)); }
void Program::BindAttribute(VertexAttributes attrib, const std::string& attribute) const { assert(!IsLinked()); glBindAttribLocation(mProgram, GLenum(attrib), attribute.data()); }
void GLReplay::SavePipelineState() { GLPipelineState &pipe = m_CurPipelineState; WrappedOpenGL &gl = *m_pDriver; GLResourceManager *rm = m_pDriver->GetResourceManager(); MakeCurrentReplayContext(&m_ReplayCtx); // Index buffer pipe.m_VtxIn.ibuffer.Offset = m_pDriver->m_LastIndexOffset; pipe.m_VtxIn.ibuffer.Format = ResourceFormat(); pipe.m_VtxIn.ibuffer.Format.special = false; pipe.m_VtxIn.ibuffer.Format.compCount = 1; pipe.m_VtxIn.ibuffer.Format.compType = eCompType_UInt; switch(m_pDriver->m_LastIndexSize) { default: break; case eGL_UNSIGNED_BYTE: pipe.m_VtxIn.ibuffer.Format.compByteWidth = 1; pipe.m_VtxIn.ibuffer.Format.strname = L"GL_UNSIGNED_BYTE"; break; case eGL_UNSIGNED_SHORT: pipe.m_VtxIn.ibuffer.Format.compByteWidth = 2; pipe.m_VtxIn.ibuffer.Format.strname = L"GL_UNSIGNED_SHORT"; break; case eGL_UNSIGNED_INT: pipe.m_VtxIn.ibuffer.Format.compByteWidth = 4; pipe.m_VtxIn.ibuffer.Format.strname = L"GL_UNSIGNED_INT"; break; } GLint curIdxBuf = 0; gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, &curIdxBuf); pipe.m_VtxIn.ibuffer.Buffer = rm->GetOriginalID(rm->GetID(BufferRes(curIdxBuf))); // Vertex buffers and attributes GLint numVBufferBindings = 16; gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings); GLint numVAttribBindings = 16; gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, &numVAttribBindings); create_array_uninit(pipe.m_VtxIn.vbuffers, numVBufferBindings); create_array_uninit(pipe.m_VtxIn.attributes, numVAttribBindings); for(GLuint i=0; i < (GLuint)numVBufferBindings; i++) { GLint vb = 0; gl.glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, i, &vb); pipe.m_VtxIn.vbuffers[i].Buffer = rm->GetOriginalID(rm->GetID(BufferRes(vb))); gl.glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Stride); gl.glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Offset); gl.glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Divisor); pipe.m_VtxIn.vbuffers[i].PerInstance = (pipe.m_VtxIn.vbuffers[i].Divisor != 0); } for(GLuint i=0; i < (GLuint)numVAttribBindings; i++) { gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_ENABLED, (GLint *)&pipe.m_VtxIn.attributes[i].Enabled); gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_BINDING, (GLint *)&pipe.m_VtxIn.attributes[i].BufferSlot); gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_RELATIVE_OFFSET, (GLint*)&pipe.m_VtxIn.attributes[i].RelativeOffset); GLenum type = eGL_FLOAT; GLint normalized = 0; gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint *)&type); gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized); ResourceFormat fmt; fmt.special = false; fmt.compCount = 4; gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint *)&fmt.compCount); switch(type) { default: case eGL_BYTE: fmt.compByteWidth = 1; fmt.compType = normalized ? eCompType_SInt : eCompType_SNorm; fmt.strname = StringFormat::WFmt(L"GL_BYTE%d", fmt.compCount) + (normalized ? L"" : L"_SNORM"); break; case eGL_UNSIGNED_BYTE: fmt.compByteWidth = 1; fmt.compType = normalized ? eCompType_UInt : eCompType_UNorm; fmt.strname = StringFormat::WFmt(L"GL_UNSIGNED_BYTE%d", fmt.compCount) + (normalized ? L"" : L"_UNORM"); break; case eGL_SHORT: fmt.compByteWidth = 2; fmt.compType = normalized ? eCompType_SInt : eCompType_SNorm; fmt.strname = StringFormat::WFmt(L"GL_SHORT%d", fmt.compCount) + (normalized ? L"" : L"_SNORM"); break; case eGL_UNSIGNED_SHORT: fmt.compByteWidth = 2; fmt.compType = normalized ? eCompType_UInt : eCompType_UNorm; fmt.strname = StringFormat::WFmt(L"GL_UNSIGNED_SHORT%d", fmt.compCount) + (normalized ? L"" : L"_UNORM"); break; case eGL_INT: fmt.compByteWidth = 4; fmt.compType = normalized ? eCompType_SInt : eCompType_SNorm; fmt.strname = StringFormat::WFmt(L"GL_INT%d", fmt.compCount) + (normalized ? L"" : L"_SNORM"); break; case eGL_UNSIGNED_INT: fmt.compByteWidth = 4; fmt.compType = normalized ? eCompType_UInt : eCompType_UNorm; fmt.strname = StringFormat::WFmt(L"GL_UNSIGNED_INT%d", fmt.compCount) + (normalized ? L"" : L"_UNORM"); break; case eGL_FLOAT: fmt.compByteWidth = 4; fmt.compType = eCompType_Float; fmt.strname = StringFormat::WFmt(L"GL_FLOAT%d", fmt.compCount); break; case eGL_DOUBLE: fmt.compByteWidth = 8; fmt.compType = eCompType_Double; fmt.strname = StringFormat::WFmt(L"GL_DOUBLE%d", fmt.compCount); break; case eGL_HALF_FLOAT: fmt.compByteWidth = 2; fmt.compType = eCompType_Float; fmt.strname = StringFormat::WFmt(L"GL_HALF_FLOAT%d", fmt.compCount); break; case eGL_INT_2_10_10_10_REV: fmt.special = true; fmt.specialFormat = eSpecial_R10G10B10A2; fmt.compCount = 4; fmt.compType = eCompType_UInt; fmt.strname = L"GL_INT_2_10_10_10_REV"; break; case eGL_UNSIGNED_INT_2_10_10_10_REV: fmt.special = true; fmt.specialFormat = eSpecial_R10G10B10A2; fmt.compCount = 4; fmt.compType = eCompType_SInt; fmt.strname = L"eGL_UNSIGNED_INT_2_10_10_10_REV"; break; case eGL_UNSIGNED_INT_10F_11F_11F_REV: fmt.special = true; fmt.specialFormat = eSpecial_R11G11B10; fmt.compCount = 3; fmt.compType = eCompType_SInt; fmt.strname = L"eGL_UNSIGNED_INT_10F_11F_11F_REV"; break; } pipe.m_VtxIn.attributes[i].Format = fmt; } switch(m_pDriver->m_LastDrawMode) { default: pipe.m_VtxIn.Topology = eTopology_Unknown; break; case GL_POINTS: pipe.m_VtxIn.Topology = eTopology_PointList; break; case GL_LINE_STRIP: pipe.m_VtxIn.Topology = eTopology_LineStrip; break; case GL_LINE_LOOP: pipe.m_VtxIn.Topology = eTopology_LineLoop; break; case GL_LINES: pipe.m_VtxIn.Topology = eTopology_LineList; break; case GL_LINE_STRIP_ADJACENCY: pipe.m_VtxIn.Topology = eTopology_LineStrip_Adj; break; case GL_LINES_ADJACENCY: pipe.m_VtxIn.Topology = eTopology_LineList_Adj; break; case GL_TRIANGLE_STRIP: pipe.m_VtxIn.Topology = eTopology_TriangleStrip; break; case GL_TRIANGLE_FAN: pipe.m_VtxIn.Topology = eTopology_TriangleFan; break; case GL_TRIANGLES: pipe.m_VtxIn.Topology = eTopology_TriangleList; break; case GL_TRIANGLE_STRIP_ADJACENCY: pipe.m_VtxIn.Topology = eTopology_TriangleStrip_Adj; break; case GL_TRIANGLES_ADJACENCY: pipe.m_VtxIn.Topology = eTopology_TriangleList_Adj; break; case GL_PATCHES: { GLint patchCount = 3; gl.glGetIntegerv(eGL_PATCH_VERTICES, &patchCount); pipe.m_VtxIn.Topology = PrimitiveTopology(eTopology_PatchList_1CPs+patchCount); break; } } // Shader stages GLuint curProg = 0; gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint*)&curProg); auto &progDetails = m_pDriver->m_Programs[rm->GetID(ProgramRes(curProg))]; RDCASSERT(progDetails.shaders.size()); for(size_t i=0; i < progDetails.shaders.size(); i++) { if(m_pDriver->m_Shaders[ progDetails.shaders[i] ].type == eGL_VERTEX_SHADER) pipe.m_VS.Shader = rm->GetOriginalID(progDetails.shaders[i]); else if(m_pDriver->m_Shaders[ progDetails.shaders[i] ].type == eGL_FRAGMENT_SHADER) pipe.m_FS.Shader = rm->GetOriginalID(progDetails.shaders[i]); } pipe.m_VS.stage = eShaderStage_Vertex; pipe.m_TCS.stage = eShaderStage_Tess_Control; pipe.m_TES.stage = eShaderStage_Tess_Eval; pipe.m_GS.stage = eShaderStage_Geometry; pipe.m_FS.stage = eShaderStage_Fragment; pipe.m_CS.stage = eShaderStage_Compute; // Textures GLint numTexUnits = 8; gl.glGetIntegerv(eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits); create_array_uninit(pipe.Textures, numTexUnits); GLenum activeTexture = eGL_TEXTURE0; gl.glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint*)&activeTexture); // GL is ass-backwards in its handling of texture units. When a shader is active // the types in the glsl samplers inform which targets are used from which texture units // // So texture unit 5 can have a 2D bound (texture 52) and a Cube bound (texture 77). // * if a uniform sampler2D has value 5 then the 2D texture is used, and we sample from 52 // * if a uniform samplerCube has value 5 then the Cube texture is used, and we sample from 77 // It's illegal for both a sampler2D and samplerCube to both have the same value (or any two // different types). It makes it all rather pointless and needlessly complex. // // What we have to do then, is consider the program, look at the values of the uniforms, and // then get the appropriate current binding based on the uniform type. We can warn/alert the // user if we hit the illegal case of two uniforms with different types but the same value // // Handling is different if no shaders are active, but we don't consider that case. // prefetch uniform values in GetShader() ShaderReflection *refls[6]; for(size_t s=0; s < progDetails.shaders.size(); s++) refls[s] = GetShader(progDetails.shaders[s]); for(GLint unit=0; unit < numTexUnits; unit++) { GLenum binding = eGL_UNKNOWN_ENUM; GLenum target = eGL_UNKNOWN_ENUM; for(size_t s=0; s < progDetails.shaders.size(); s++) { if(refls[s] == NULL) continue; for(int32_t r=0; r < refls[s]->Resources.count; r++) { // bindPoint is the uniform value for this sampler if(refls[s]->Resources[r].bindPoint == (uint32_t)unit) { GLenum t = eGL_UNKNOWN_ENUM; switch(refls[s]->Resources[r].resType) { case eResType_None: t = eGL_UNKNOWN_ENUM; break; case eResType_Buffer: t = eGL_TEXTURE_BINDING_BUFFER; break; case eResType_Texture1D: t = eGL_TEXTURE_BINDING_1D; target = eGL_TEXTURE_1D; break; case eResType_Texture1DArray: t = eGL_TEXTURE_BINDING_1D_ARRAY; target = eGL_TEXTURE_1D_ARRAY; break; case eResType_Texture2D: t = eGL_TEXTURE_BINDING_2D; target = eGL_TEXTURE_2D; break; case eResType_Texture2DArray: t = eGL_TEXTURE_BINDING_2D_ARRAY; target = eGL_TEXTURE_2D_ARRAY; break; case eResType_Texture2DMS: t = eGL_TEXTURE_BINDING_2D_MULTISAMPLE; target = eGL_TEXTURE_2D_MULTISAMPLE; break; case eResType_Texture2DMSArray: t = eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; target = eGL_TEXTURE_2D_MULTISAMPLE_ARRAY; break; case eResType_Texture3D: t = eGL_TEXTURE_BINDING_3D; target = eGL_TEXTURE_3D; break; case eResType_TextureCube: t = eGL_TEXTURE_BINDING_CUBE_MAP; target = eGL_TEXTURE_CUBE_MAP; break; case eResType_TextureCubeArray: t = eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY; target = eGL_TEXTURE_CUBE_MAP_ARRAY; break; } if(binding == eGL_UNKNOWN_ENUM) { binding = t; } else if(binding == t) { // two uniforms with the same type pointing to the same slot is fine binding = t; } else if(binding != t) { RDCWARN("Two uniforms pointing to texture unit %d with types %s and %s", unit, ToStr::Get(binding).c_str(), ToStr::Get(t).c_str()); } } } } if(binding != eGL_UNKNOWN_ENUM) { gl.glActiveTexture(GLenum(eGL_TEXTURE0+unit)); GLuint tex; gl.glGetIntegerv(binding, (GLint *)&tex); // very bespoke/specific GLint firstSlice = 0; gl.glGetTexParameteriv(target, eGL_TEXTURE_VIEW_MIN_LEVEL, &firstSlice); pipe.Textures[unit].Resource = rm->GetOriginalID(rm->GetID(TextureRes(tex))); pipe.Textures[unit].FirstSlice = (uint32_t)firstSlice; } else { // what should we do in this case? there could be something bound just not used, // it'd be nice to return that } } gl.glActiveTexture(activeTexture); GLuint curFBO = 0; gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curFBO); GLint numCols = 8; gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); GLuint curCol[32] = { 0 }; GLuint curDepth = 0; GLuint curStencil = 0; RDCASSERT(numCols <= 32); // we should never bind the true default framebuffer - if the app did, we will have our fake bound RDCASSERT(curFBO != 0); { for(GLint i=0; i < numCols; i++) gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curCol[i]); gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curDepth); gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curStencil); } pipe.m_FB.FBO = rm->GetOriginalID(rm->GetID(FramebufferRes(curFBO))); create_array_uninit(pipe.m_FB.Color, numCols); for(GLint i=0; i < numCols; i++) pipe.m_FB.Color[i] = rm->GetOriginalID(rm->GetID(TextureRes(curCol[i]))); pipe.m_FB.Depth = rm->GetOriginalID(rm->GetID(TextureRes(curDepth))); pipe.m_FB.Stencil = rm->GetOriginalID(rm->GetID(TextureRes(curStencil))); }
void* Buffer::mapSub(const GLintptr offset, const GLsizeiptr length, const MapAccess access) { /** @todo Enable also in Emscripten (?) when extension wrangler is available */ #ifdef CORRADE_TARGET_NACL CORRADE_ASSERT(!_mappedBuffer, "Buffer::mapSub(): the buffer is already mapped", nullptr); return _mappedBuffer = glMapBufferSubDataCHROMIUM(static_cast<GLenum>(bindInternal(_targetHint)), offset, length, GLenum(access)); #else CORRADE_INTERNAL_ASSERT(false); static_cast<void>(offset); static_cast<void>(length); static_cast<void>(access); #endif }
void CubeMapTexture::getImageImplementationDSA(const Coordinate coordinate, const GLint level, const Vector2i& size, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { glGetTextureSubImage(_id, level, 0, 0, GLenum(coordinate) - GL_TEXTURE_CUBE_MAP_POSITIVE_X, size.x(), size.y(), 1, GLenum(format), GLenum(type), dataSize, data); }
/** * @glsymbols * @glfunref{BlendFunc} */ static void BlendFunc(BlendFunction src, BlendFunction dst) { OGLPLUS_GLFUNC(BlendFunc)(GLenum(src), GLenum(dst)); OGLPLUS_VERIFY_SIMPLE(BlendFunc); }
void CubeMapTexture::getImageImplementationRobustness(const Coordinate coordinate, const GLint level, const Vector2i&, const ColorFormat format, const ColorType type, const std::size_t dataSize, GLvoid* const data) { bindInternal(); glGetnTexImageARB(GLenum(coordinate), level, GLenum(format), GLenum(type), dataSize, data); }
/** * @glsymbols * @glfunref{BlendEquation} */ static void BlendEquation(oglplus::BlendEquation eq) { OGLPLUS_GLFUNC(BlendEquation)(GLenum(eq)); OGLPLUS_VERIFY_SIMPLE(BlendEquation); }
void CubeMapTexture::subImageImplementationDSA(const Coordinate coordinate, const GLint level, const Vector2i& offset, const Vector2i& size, const ColorFormat format, const ColorType type, const GLvoid* const data) { glTextureSubImage3D(_id, level, offset.x(), offset.y(), GLenum(coordinate) - GL_TEXTURE_CUBE_MAP_POSITIVE_X, size.x(), size.y(), 1, GLenum(format), GLenum(type), data); }
void Renderbuffer::storageMultisampleImplementationDefault(const GLsizei samples, const RenderbufferFormat internalFormat, const Vector2i& size) { bind(); glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GLenum(internalFormat), size.x(), size.y()); }
GLenum ProgramGL::getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const { UNIMPLEMENTED(); return GLenum(); }
void Renderbuffer::storageMultisampleImplementationDSA(const GLsizei samples, const RenderbufferFormat internalFormat, const Vector2i& size) { glNamedRenderbufferStorageMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y()); }
GLenum ProgramGL::getBinaryFormat() { UNIMPLEMENTED(); return GLenum(); }
void Renderbuffer::storageMultisampleImplementationDSAEXT(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size) { _flags |= ObjectFlag::Created; glNamedRenderbufferStorageMultisampleEXT(_id, samples, GLenum(internalFormat), size.x(), size.y()); }
/*! \internal */ QCLImage3D QCLContextGL::createTexture3D (QMacCompatGLuint texture, QCLMemoryObject::Access access) { return createTexture3D(GLenum(GL_TEXTURE_3D), GLuint(texture), GLint(0), access); }
ShadeModelChunkBase::ShadeModelChunkBase(void) : Inherited(), _sfShadeModel (GLenum(GL_SMOOTH)) { }