/* Context activation is done by the caller. */ static void shader_resource_view_bind_and_dirtify(struct wined3d_shader_resource_view *view, struct wined3d_context *context) { if (context->active_texture < ARRAY_SIZE(context->rev_tex_unit_map)) { DWORD active_sampler = context->rev_tex_unit_map[context->active_texture]; if (active_sampler != WINED3D_UNMAPPED_STAGE) context_invalidate_state(context, STATE_SAMPLER(active_sampler)); } /* FIXME: Ideally we'd only do this when touching a binding that's used by * a shader. */ context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); context_bind_texture(context, view->gl_view.target, view->gl_view.name); }
/* Context activation is done by the caller. */ void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb) { DWORD active_sampler; /* We don't need a specific texture unit, but after binding the texture * the current unit is dirty. Read the unit back instead of switching to * 0, this avoids messing around with the state manager's GL states. The * current texture unit should always be a valid one. * * To be more specific, this is tricky because we can implicitly be * called from sampler() in state.c. This means we can't touch anything * other than whatever happens to be the currently active texture, or we * would risk marking already applied sampler states dirty again. */ active_sampler = context->rev_tex_unit_map[context->active_texture]; if (active_sampler != WINED3D_UNMAPPED_STAGE) context_invalidate_state(context, STATE_SAMPLER(active_sampler)); wined3d_texture_bind(texture, context, srgb); }
static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_context *context, struct wined3d_buffer *buffer, const struct wined3d_format *view_format, unsigned int offset, unsigned int size) { const struct wined3d_gl_info *gl_info = context->gl_info; if (!gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT]) { FIXME("OpenGL implementation does not support buffer textures.\n"); return; } if ((offset & (gl_info->limits.texture_buffer_offset_alignment - 1))) { FIXME("Buffer offset %u is not %u byte aligned.\n", offset, gl_info->limits.texture_buffer_offset_alignment); return; } wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER); view->target = GL_TEXTURE_BUFFER; gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); context_bind_texture(context, GL_TEXTURE_BUFFER, view->name); if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE]) { GL_EXTCALL(glTexBufferRange(GL_TEXTURE_BUFFER, view_format->glInternal, buffer->buffer_object, offset, size)); } else { if (offset || size != buffer->resource.size) FIXME("OpenGL implementation does not support ARB_texture_buffer_range.\n"); GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, view_format->glInternal, buffer->buffer_object)); } checkGLcall("Create buffer texture"); context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); }
/* A GL context is provided by the caller */ static void swapchain_blit(const struct wined3d_swapchain *swapchain, struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect) { struct wined3d_surface *backbuffer = swapchain->back_buffers[0]; UINT src_w = src_rect->right - src_rect->left; UINT src_h = src_rect->bottom - src_rect->top; GLenum gl_filter; const struct wined3d_gl_info *gl_info = context->gl_info; RECT win_rect; UINT win_h; TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n", swapchain, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect)); if (src_w == dst_rect->right - dst_rect->left && src_h == dst_rect->bottom - dst_rect->top) gl_filter = GL_NEAREST; else gl_filter = GL_LINEAR; GetClientRect(swapchain->win_handle, &win_rect); win_h = win_rect.bottom - win_rect.top; if (gl_info->fbo_ops.glBlitFramebuffer && is_identity_fixup(backbuffer->resource.format->color_fixup)) { DWORD location = SFLAG_INTEXTURE; if (backbuffer->resource.multisample_type) { location = SFLAG_INRB_RESOLVED; surface_load_location(backbuffer, location, NULL); } ENTER_GL(); context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL, location); glReadBuffer(GL_COLOR_ATTACHMENT0); context_check_fbo_status(context, GL_READ_FRAMEBUFFER); context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, swapchain->front_buffer, NULL, SFLAG_INDRAWABLE); context_set_draw_buffer(context, GL_BACK); context_invalidate_state(context, STATE_FRAMEBUFFER); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE)); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1)); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2)); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3)); glDisable(GL_SCISSOR_TEST); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE)); /* Note that the texture is upside down */ gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, dst_rect->left, win_h - dst_rect->top, dst_rect->right, win_h - dst_rect->bottom, GL_COLOR_BUFFER_BIT, gl_filter); checkGLcall("Swapchain present blit(EXT_framebuffer_blit)\n"); LEAVE_GL(); } else { struct wined3d_device *device = swapchain->device; struct wined3d_context *context2; float tex_left = src_rect->left; float tex_top = src_rect->top; float tex_right = src_rect->right; float tex_bottom = src_rect->bottom; context2 = context_acquire(device, swapchain->back_buffers[0]); context_apply_blit_state(context2, device); if (backbuffer->flags & SFLAG_NORMCOORD) { tex_left /= src_w; tex_right /= src_w; tex_top /= src_h; tex_bottom /= src_h; } if (is_complex_fixup(backbuffer->resource.format->color_fixup)) gl_filter = GL_NEAREST; ENTER_GL(); context_apply_fbo_state_blit(context2, GL_FRAMEBUFFER, swapchain->front_buffer, NULL, SFLAG_INDRAWABLE); /* Set up the texture. The surface is not in a wined3d_texture * container, so there are no D3D texture settings to dirtify. */ device->blitter->set_shader(device->blit_priv, context2, backbuffer); glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, gl_filter); glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, gl_filter); context_set_draw_buffer(context, GL_BACK); /* Set the viewport to the destination rectandle, disable any projection * transformation set up by context_apply_blit_state(), and draw a * (-1,-1)-(1,1) quad. * * Back up viewport and matrix to avoid breaking last_was_blit * * Note that context_apply_blit_state() set up viewport and ortho to * match the surface size - we want the GL drawable(=window) size. */ glPushAttrib(GL_VIEWPORT_BIT); glViewport(dst_rect->left, win_h - dst_rect->bottom, dst_rect->right, win_h - dst_rect->top); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glBegin(GL_QUADS); /* bottom left */ glTexCoord2f(tex_left, tex_bottom); glVertex2i(-1, -1); /* top left */ glTexCoord2f(tex_left, tex_top); glVertex2i(-1, 1); /* top right */ glTexCoord2f(tex_right, tex_top); glVertex2i(1, 1); /* bottom right */ glTexCoord2f(tex_right, tex_bottom); glVertex2i(1, -1); glEnd(); glPopMatrix(); glPopAttrib(); device->blitter->unset_shader(context->gl_info); checkGLcall("Swapchain present blit(manual)\n"); LEAVE_GL(); context_release(context2); } }
static void create_texture_view(struct wined3d_gl_view *view, GLenum view_target, const struct wined3d_view_desc *desc, struct wined3d_texture *texture, const struct wined3d_format *view_format) { const struct wined3d_gl_info *gl_info; unsigned int layer_idx, layer_count; struct wined3d_context *context; GLuint texture_name; view->target = view_target; context = context_acquire(texture->resource.device, NULL, 0); gl_info = context->gl_info; if (!gl_info->supported[ARB_TEXTURE_VIEW]) { context_release(context); FIXME("OpenGL implementation does not support texture views.\n"); return; } wined3d_texture_prepare_texture(texture, context, FALSE); texture_name = wined3d_texture_get_texture_name(texture, context, FALSE); layer_idx = desc->u.texture.layer_idx; layer_count = desc->u.texture.layer_count; if (view_target == GL_TEXTURE_3D && (layer_idx || layer_count != 1)) { FIXME("Depth slice (%u-%u) not supported.\n", layer_idx, layer_count); layer_idx = 0; layer_count = 1; } gl_info->gl_ops.gl.p_glGenTextures(1, &view->name); GL_EXTCALL(glTextureView(view->name, view->target, texture_name, view_format->glInternal, desc->u.texture.level_idx, desc->u.texture.level_count, layer_idx, layer_count)); checkGLcall("Create texture view"); if (is_stencil_view_format(view_format)) { static const GLint swizzle[] = {GL_ZERO, GL_RED, GL_ZERO, GL_ZERO}; if (!gl_info->supported[ARB_STENCIL_TEXTURING]) { context_release(context); FIXME("OpenGL implementation does not support stencil texturing.\n"); return; } context_bind_texture(context, view->target, view->name); gl_info->gl_ops.gl.p_glTexParameteriv(view->target, GL_TEXTURE_SWIZZLE_RGBA, swizzle); gl_info->gl_ops.gl.p_glTexParameteri(view->target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); checkGLcall("Initialize stencil view"); context_invalidate_compute_state(context, STATE_COMPUTE_SHADER_RESOURCE_BINDING); context_invalidate_state(context, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); } context_release(context); }