/* Context activation is done by the caller. */ static void wined3d_volume_download_data(struct wined3d_volume *volume, const struct wined3d_context *context, const struct wined3d_bo_address *data) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; if (format->convert) { FIXME("Attempting to download a converted volume, format %s.\n", debug_d3dformat(format->id)); return; } if (data->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data->buffer_object)); checkGLcall("glBindBufferARB"); } gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, volume->texture_level, format->glFormat, format->glType, data->addr); checkGLcall("glGetTexImage"); if (data->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0)); checkGLcall("glBindBufferARB"); } }
/* Context activation is done by the caller. */ static void wined3d_volume_allocate_texture(struct wined3d_volume *volume, const struct wined3d_context *context, BOOL srgb) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; void *mem = NULL; if (gl_info->supported[APPLE_CLIENT_STORAGE] && !format->convert && volume_prepare_system_memory(volume)) { TRACE("Enabling GL_UNPACK_CLIENT_STORAGE_APPLE for volume %p\n", volume); gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)"); mem = volume->resource.heap_memory; volume->flags |= WINED3D_VFLAG_CLIENT_STORAGE; } GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, volume->texture_level, srgb ? format->glGammaInternal : format->glInternal, volume->resource.width, volume->resource.height, volume->resource.depth, 0, format->glFormat, format->glType, mem)); checkGLcall("glTexImage3D"); if (mem) { gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)"); } }
/* Context activation is optionally by the caller. Context may be NULL. */ static void wined3d_resource_copy_simple_location(struct wined3d_resource *resource, struct wined3d_context *context, DWORD location) { const struct wined3d_gl_info *gl_info; struct wined3d_bo_address dst, src; UINT size = resource->size; wined3d_resource_get_memory(resource, location, &dst); wined3d_resource_get_memory(resource, resource->locations, &src); if (dst.buffer_object) { gl_info = context->gl_info; GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object)); GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr)); GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("Upload PBO"); return; } if (src.buffer_object) { gl_info = context->gl_info; GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object)); GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr)); GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); checkGLcall("Download PBO"); return; } memcpy(dst.addr, src.addr, size); }
/* Context activation is done by the caller. */ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, const struct wined3d_bo_address *data) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; TRACE("volume %p, context %p, level %u, format %s (%#x).\n", volume, context, volume->texture_level, debug_d3dformat(format->id), format->id); if (data->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, data->buffer_object)); checkGLcall("glBindBufferARB"); } GL_EXTCALL(glTexSubImage3DEXT(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0, volume->resource.width, volume->resource.height, volume->resource.depth, format->glFormat, format->glType, data->addr)); checkGLcall("glTexSubImage3D"); if (data->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); checkGLcall("glBindBufferARB"); } }
static HRESULT wined3d_timestamp_query_ops_get_data(struct wined3d_query *query, void *data, DWORD size, DWORD flags) { struct wined3d_timestamp_query *tq = query->extendedData; struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context; GLuint available; GLuint64 timestamp; HRESULT res; TRACE("query %p, data %p, size %#x, flags %#x.\n", query, data, size, flags); if (!tq->context) query->state = QUERY_CREATED; if (query->state == QUERY_CREATED) { /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves. */ TRACE("Query wasn't yet started, returning S_OK.\n"); timestamp = 0; fill_query_data(data, size, ×tamp, sizeof(timestamp)); return S_OK; } if (tq->context->tid != GetCurrentThreadId()) { FIXME("%p Wrong thread, returning 1.\n", query); timestamp = 1; fill_query_data(data, size, ×tamp, sizeof(timestamp)); return S_OK; } context = context_acquire(query->device, tq->context->current_rt); GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available)); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); TRACE("available %#x.\n", available); if (available) { if (size) { GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); fill_query_data(data, size, ×tamp, sizeof(timestamp)); } res = S_OK; } else { res = S_FALSE; } context_release(context); return res; }
/* Context activation is done by the caller. */ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, const struct wined3d_const_bo_address *data) { const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_texture *texture = volume->container; const struct wined3d_format *format = texture->resource.format; unsigned int width, height, depth; const void *mem = data->addr; void *converted_mem = NULL; TRACE("volume %p, context %p, level %u, format %s (%#x).\n", volume, context, volume->texture_level, debug_d3dformat(format->id), format->id); width = wined3d_texture_get_level_width(texture, volume->texture_level); height = wined3d_texture_get_level_height(texture, volume->texture_level); depth = wined3d_texture_get_level_depth(texture, volume->texture_level); if (format->convert) { UINT dst_row_pitch, dst_slice_pitch; UINT src_row_pitch, src_slice_pitch; if (data->buffer_object) ERR("Loading a converted volume from a PBO.\n"); if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS) ERR("Converting a block-based format.\n"); dst_row_pitch = width * format->conv_byte_count; dst_slice_pitch = dst_row_pitch * height; wined3d_texture_get_pitch(texture, volume->texture_level, &src_row_pitch, &src_slice_pitch); converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, width, height, depth); mem = converted_mem; } if (data->buffer_object) { GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object)); checkGLcall("glBindBuffer"); } GL_EXTCALL(glTexSubImage3D(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0, width, height, depth, format->glFormat, format->glType, mem)); checkGLcall("glTexSubImage3D"); if (data->buffer_object) { GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("glBindBuffer"); } HeapFree(GetProcessHeap(), 0, converted_mem); }
/* Context activation is done by the caller. */ static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface, BOOL srgb) { IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; BOOL set_gl_texture_desc; HRESULT hr; TRACE("(%p) : relay to BaseTexture\n", This); #ifdef VBOX_WITH_WDDM Assert(!VBOXSHRC_IS_DISABLED(This)); #endif hr = basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &set_gl_texture_desc); if (set_gl_texture_desc && SUCCEEDED(hr)) { UINT i; struct gl_texture *gl_tex; if(This->baseTexture.is_srgb) { gl_tex = &This->baseTexture.texture_srgb; } else { gl_tex = &This->baseTexture.texture_rgb; } for (i = 0; i < This->baseTexture.levels; ++i) { surface_set_texture_name(This->surfaces[i], gl_tex->name, This->baseTexture.is_srgb); } /* Conditinal non power of two textures use a different clamping default. If we're using the GL_WINE_normalized_texrect * partial driver emulation, we're dealing with a GL_TEXTURE_2D texture which has the address mode set to repeat - something * that prevents us from hitting the accelerated codepath. Thus manually set the GL state. The same applies to filtering. * Even if the texture has only one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW fallback on macos. */ if(IWineD3DBaseTexture_IsCondNP2(iface)) { #ifdef VBOX_WITH_WDDM if (!VBOXSHRC_IS_SHARED_OPENED(This)) #endif { ENTER_GL(); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)"); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)"); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)"); LEAVE_GL(); } gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3DTADDRESS_CLAMP; gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3DTADDRESS_CLAMP; gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT; gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE; } } return hr; }
/* Context activation is done by the caller. */ static HRESULT texture2d_bind(struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info, BOOL srgb) { BOOL set_gl_texture_desc; HRESULT hr; TRACE("texture %p, gl_info %p, srgb %#x.\n", texture, gl_info, srgb); hr = wined3d_texture_bind(texture, gl_info, srgb, &set_gl_texture_desc); if (set_gl_texture_desc && SUCCEEDED(hr)) { UINT sub_count = texture->level_count * texture->layer_count; BOOL srgb_tex = !gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && (texture->flags & WINED3D_TEXTURE_IS_SRGB); struct gl_texture *gl_tex; UINT i; gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, srgb_tex); for (i = 0; i < sub_count; ++i) { struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]); surface_set_texture_name(surface, gl_tex->name, srgb_tex); } /* Conditinal non power of two textures use a different clamping * default. If we're using the GL_WINE_normalized_texrect partial * driver emulation, we're dealing with a GL_TEXTURE_2D texture which * has the address mode set to repeat - something that prevents us * from hitting the accelerated codepath. Thus manually set the GL * state. The same applies to filtering. Even if the texture has only * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW * fallback on macos. */ if (texture->flags & WINED3D_TEXTURE_COND_NP2) { GLenum target = texture->target; ENTER_GL(); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)"); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)"); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)"); LEAVE_GL(); gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3DTADDRESS_CLAMP; gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3DTADDRESS_CLAMP; gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT; gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE; } } return hr; }
/* Context activation is done by the caller. */ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wined3d_context *context, const struct wined3d_bo_address *data) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; UINT width = volume->resource.width; UINT height = volume->resource.height; UINT depth = volume->resource.depth; BYTE *mem = data->addr; TRACE("volume %p, context %p, level %u, format %s (%#x).\n", volume, context, volume->texture_level, debug_d3dformat(format->id), format->id); if (format->convert) { UINT dst_row_pitch, dst_slice_pitch; UINT src_row_pitch, src_slice_pitch; UINT alignment = volume->resource.device->surface_alignment; if (data->buffer_object) ERR("Loading a converted volume from a PBO.\n"); if (format->flags & WINED3DFMT_FLAG_BLOCKS) ERR("Converting a block-based format.\n"); dst_row_pitch = width * format->conv_byte_count; dst_row_pitch = (dst_row_pitch + alignment - 1) & ~(alignment - 1); dst_slice_pitch = dst_row_pitch * height; wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch); mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); format->convert(data->addr, mem, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, width, height, depth); } if (data->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, data->buffer_object)); checkGLcall("glBindBufferARB"); } GL_EXTCALL(glTexSubImage3DEXT(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0, width, height, depth, format->glFormat, format->glType, mem)); checkGLcall("glTexSubImage3D"); if (data->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); checkGLcall("glBindBufferARB"); } if (mem != data->addr) HeapFree(GetProcessHeap(), 0, mem); }
/* Context activation is done by the caller. */ static HRESULT texture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb) { BOOL set_gl_texture_desc; HRESULT hr; TRACE("texture %p, srgb %#x.\n", texture, srgb); hr = basetexture_bind(texture, srgb, &set_gl_texture_desc); if (set_gl_texture_desc && SUCCEEDED(hr)) { UINT i; struct gl_texture *gl_tex; if (texture->baseTexture.is_srgb) gl_tex = &texture->baseTexture.texture_srgb; else gl_tex = &texture->baseTexture.texture_rgb; for (i = 0; i < texture->baseTexture.level_count; ++i) { IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i]; surface_set_texture_name(surface, gl_tex->name, texture->baseTexture.is_srgb); } /* Conditinal non power of two textures use a different clamping * default. If we're using the GL_WINE_normalized_texrect partial * driver emulation, we're dealing with a GL_TEXTURE_2D texture which * has the address mode set to repeat - something that prevents us * from hitting the accelerated codepath. Thus manually set the GL * state. The same applies to filtering. Even if the texture has only * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW * fallback on macos. */ if (IWineD3DBaseTexture_IsCondNP2((IWineD3DBaseTexture *)texture)) { GLenum target = texture->baseTexture.target; ENTER_GL(); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)"); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)"); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)"); LEAVE_GL(); gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3DTADDRESS_CLAMP; gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3DTADDRESS_CLAMP; gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT; gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE; } } return hr; }
void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device) { const struct wined3d_gl_info *gl_info; struct wined3d_context *context; if (query->context) { if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId()) { #ifdef VBOX_WINE_WITH_SINGLE_CONTEXT ERR("unexpected\n"); #endif context_free_event_query(query); context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); context_alloc_event_query(context, query); } else { context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD); } } else { context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD); context_alloc_event_query(context, query); } gl_info = context->gl_info; ENTER_GL(); if (gl_info->supported[ARB_SYNC]) { if (query->object.sync) GL_EXTCALL(glDeleteSync(query->object.sync)); checkGLcall("glDeleteSync"); query->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); checkGLcall("glFenceSync"); } else if (gl_info->supported[APPLE_FENCE]) { GL_EXTCALL(glSetFenceAPPLE(query->object.id)); checkGLcall("glSetFenceAPPLE"); } else if (gl_info->supported[NV_FENCE]) { GL_EXTCALL(glSetFenceNV(query->object.id, GL_ALL_COMPLETED_NV)); checkGLcall("glSetFenceNV"); } LEAVE_GL(); context_release(context); }
/* GL locking is done by the caller */ static void drawStridedFast(GLenum primitive_type, UINT count, UINT idx_size, const void *idx_data, UINT start_idx) { if (idx_size) { glDrawElements(primitive_type, count, idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (const char *)idx_data + (idx_size * start_idx)); checkGLcall("glDrawElements"); } else { glDrawArrays(primitive_type, start_idx, count); checkGLcall("glDrawArrays"); } }
static void wined3d_shader_resource_view_create_texture_view(struct wined3d_shader_resource_view *view, const struct wined3d_shader_resource_view_desc *desc, struct wined3d_texture *texture, const struct wined3d_format *view_format) { const struct wined3d_gl_info *gl_info; struct wined3d_context *context; struct gl_texture *gl_texture; context = context_acquire(texture->resource.device, NULL); 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); gl_texture = wined3d_texture_get_gl_texture(texture, FALSE); gl_info->gl_ops.gl.p_glGenTextures(1, &view->object); GL_EXTCALL(glTextureView(view->object, view->target, gl_texture->name, view_format->glInternal, desc->u.texture.level_idx, desc->u.texture.level_count, desc->u.texture.layer_idx, desc->u.texture.layer_count)); checkGLcall("Create texture view"); context_release(context); }
void wined3d_resource_release_map_ptr(const struct wined3d_resource *resource, const struct wined3d_context *context) { const struct wined3d_gl_info *gl_info; switch (resource->map_binding) { case WINED3D_LOCATION_BUFFER: gl_info = context->gl_info; GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, resource->map_buffer->name)); GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("Unmap GL buffer"); return; case WINED3D_LOCATION_SYSMEM: case WINED3D_LOCATION_DIB: case WINED3D_LOCATION_USER_MEMORY: return; default: ERR("Unexpected map binding %s.\n", wined3d_debug_location(resource->map_binding)); return; } }
HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume) { TRACE("volume %p.\n", volume); if (!volume->resource.map_count) { WARN("Trying to unlock an unlocked volume %p.\n", volume); return WINED3DERR_INVALIDCALL; } if (volume->resource.map_binding == WINED3D_LOCATION_BUFFER) { struct wined3d_device *device = volume->resource.device; struct wined3d_context *context = context_acquire(device, NULL); const struct wined3d_gl_info *gl_info = context->gl_info; GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, volume->pbo)); GL_EXTCALL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)); GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0)); checkGLcall("Unmap PBO"); context_release(context); } volume->resource.map_count--; return WINED3D_OK; }
ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view) { ULONG refcount = InterlockedDecrement(&view->refcount); TRACE("%p decreasing refcount to %u.\n", view, refcount); if (!refcount) { if (view->object) { const struct wined3d_gl_info *gl_info; struct wined3d_context *context; context = context_acquire(view->resource->device, NULL); gl_info = context->gl_info; gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->object); checkGLcall("glDeleteTextures"); context_release(context); } /* Call wined3d_object_destroyed() before releasing the resource, * since releasing the resource may end up destroying the parent. */ view->parent_ops->wined3d_object_destroyed(view->parent); wined3d_resource_decref(view->resource); HeapFree(GetProcessHeap(), 0, view); } return refcount; }
static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, GLenum gl_level) { IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; const PixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format); if(GL_SUPPORT(EXT_TEXTURE3D)) { TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n", GL_TEXTURE_3D, gl_level, formatEntry->glInternal, This->currentDesc.Width, This->currentDesc.Height, This->currentDesc.Depth, 0, formatEntry->glFormat, formatEntry->glType, This->resource.allocatedMemory); GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, gl_level, formatEntry->glInternal, This->currentDesc.Width, This->currentDesc.Height, This->currentDesc.Depth, 0, formatEntry->glFormat, formatEntry->glType, This->resource.allocatedMemory)); checkGLcall("glTexImage3D"); } else WARN("This OpenGL implementation doesn't support 3D textures\n"); return WINED3D_OK; }
/* GL locking is done by the caller */ static void apply_wrap(const struct wined3d_gl_info *gl_info, GLenum target, WINED3DTEXTUREADDRESS d3d_wrap, GLenum param, BOOL cond_np2) { GLint gl_wrap; if (d3d_wrap < WINED3DTADDRESS_WRAP || d3d_wrap > WINED3DTADDRESS_MIRRORONCE) { FIXME("Unrecognized or unsupported WINED3DTEXTUREADDRESS %#x.\n", d3d_wrap); return; } if (target == GL_TEXTURE_CUBE_MAP_ARB || (cond_np2 && d3d_wrap == WINED3DTADDRESS_WRAP)) { /* Cubemaps are always set to clamp, regardless of the sampler state. */ gl_wrap = GL_CLAMP_TO_EDGE; } else { gl_wrap = gl_info->wrap_lookup[d3d_wrap - WINED3DTADDRESS_WRAP]; } TRACE("Setting param %#x to %#x for target %#x.\n", param, gl_wrap, target); glTexParameteri(target, param, gl_wrap); checkGLcall("glTexParameteri(target, param, gl_wrap)"); }
HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume) { TRACE("volume %p.\n", volume); if (!(volume->flags & WINED3D_VFLAG_LOCKED)) { WARN("Trying to unlock unlocked volume %p.\n", volume); return WINED3DERR_INVALIDCALL; } if (volume->flags & WINED3D_VFLAG_PBO) { struct wined3d_device *device = volume->resource.device; struct wined3d_context *context = context_acquire(device, NULL); const struct wined3d_gl_info *gl_info = context->gl_info; GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo)); GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB)); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); checkGLcall("Unmap PBO"); context_release(context); } volume->flags &= ~WINED3D_VFLAG_LOCKED; return WINED3D_OK; }
/* Context activation is done by the caller. */ static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) { IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; const struct wined3d_gl_info *gl_info = &This->resource.device->adapter->gl_info; const struct wined3d_format *format = This->resource.format; TRACE("iface %p, level %u, srgb %#x, format %s (%#x).\n", iface, gl_level, srgb_mode, debug_d3dformat(format->id), format->id); volume_bind_and_dirtify(iface); TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n", GL_TEXTURE_3D, gl_level, format->glInternal, This->currentDesc.Width, This->currentDesc.Height, This->currentDesc.Depth, 0, format->glFormat, format->glType, This->resource.allocatedMemory); ENTER_GL(); GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, gl_level, format->glInternal, This->currentDesc.Width, This->currentDesc.Height, This->currentDesc.Depth, 0, format->glFormat, format->glType, This->resource.allocatedMemory)); checkGLcall("glTexImage3D"); LEAVE_GL(); /* When adding code releasing This->resource.allocatedMemory to save data keep in mind that * GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by default if supported(GL_APPLE_client_storage). * Thus do not release This->resource.allocatedMemory if GL_APPLE_client_storage is supported. */ return WINED3D_OK; }
static BOOL wined3d_timestamp_query_ops_poll(struct wined3d_query *query) { struct wined3d_timestamp_query *tq = query->extendedData; struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context; GLuint available; GLuint64 timestamp; BOOL ret; if (!gl_info->supported[ARB_TIMER_QUERY]) { TRACE("Faking timestamp.\n"); QueryPerformanceCounter((LARGE_INTEGER *)&tq->timestamp); return TRUE; } if (tq->context->tid != GetCurrentThreadId()) { FIXME("%p Wrong thread, returning 1.\n", query); tq->timestamp = 1; return TRUE; } context = context_acquire(device, context_get_rt_surface(tq->context)); GL_EXTCALL(glGetQueryObjectuiv(tq->id, GL_QUERY_RESULT_AVAILABLE, &available)); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); TRACE("available %#x.\n", available); if (available) { GL_EXTCALL(glGetQueryObjectui64v(tq->id, GL_QUERY_RESULT, ×tamp)); checkGLcall("glGetQueryObjectui64v(GL_QUERY_RESULT)"); TRACE("Returning timestamp %s.\n", wine_dbgstr_longlong(timestamp)); tq->timestamp = timestamp; ret = TRUE; } else { ret = FALSE; } context_release(context); return ret; }
HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTextureImpl *texture, WINED3DTEXTUREFILTERTYPE filter_type) { TRACE("texture %p, filter_type %s.\n", texture, debug_d3dtexturefiltertype(filter_type)); if (!(texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) { WARN("Texture doesn't have AUTOGENMIPMAP usage.\n"); return WINED3DERR_INVALIDCALL; } if (texture->baseTexture.filterType != filter_type) { GLenum target = texture->baseTexture.target; struct wined3d_context *context; context = context_acquire(texture->resource.device, NULL); ENTER_GL(); glBindTexture(target, texture->baseTexture.texture_rgb.name); checkGLcall("glBindTexture"); switch (filter_type) { case WINED3DTEXF_NONE: case WINED3DTEXF_POINT: glTexParameteri(target, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST); checkGLcall("glTexParameteri(target, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST)"); break; case WINED3DTEXF_LINEAR: glTexParameteri(target, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); checkGLcall("glTexParameteri(target, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)"); break; default: WARN("Unexpected filter type %#x, setting to GL_NICEST.\n", filter_type); glTexParameteri(target, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); checkGLcall("glTexParameteri(target, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)"); break; } LEAVE_GL(); context_release(context); } texture->baseTexture.filterType = filter_type; return WINED3D_OK; }
void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device) { const struct wined3d_gl_info *gl_info; struct wined3d_context *context; if (query->context) { if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId()) { context_free_event_query(query); context = context_acquire(device, NULL); context_alloc_event_query(context, query); } else { context = context_acquire(device, query->context->current_rt); } } else { context = context_acquire(device, NULL); context_alloc_event_query(context, query); } gl_info = context->gl_info; if (gl_info->supported[ARB_SYNC]) { if (query->object.sync) GL_EXTCALL(glDeleteSync(query->object.sync)); checkGLcall("glDeleteSync"); query->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)); checkGLcall("glFenceSync"); } else if (gl_info->supported[APPLE_FENCE]) { GL_EXTCALL(glSetFenceAPPLE(query->object.id)); checkGLcall("glSetFenceAPPLE"); } else if (gl_info->supported[NV_FENCE]) { GL_EXTCALL(glSetFenceNV(query->object.id, GL_ALL_COMPLETED_NV)); checkGLcall("glSetFenceNV"); } context_release(context); }
HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; IWineD3DDeviceImpl *device = This->resource.device; GLenum textureDimensions = This->baseTexture.target; if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) { TRACE("(%p) : returning invalid call\n", This); return WINED3DERR_INVALIDCALL; } if(This->baseTexture.filterType != FilterType) { /* What about multithreading? Do we want all the context overhead just to set this value? * Or should we delay the applying until the texture is used for drawing? For now, apply * immediately. */ struct wined3d_context *context = context_acquire(device, NULL); ENTER_GL(); glBindTexture(textureDimensions, This->baseTexture.texture_rgb.name); checkGLcall("glBindTexture"); switch(FilterType) { case WINED3DTEXF_NONE: case WINED3DTEXF_POINT: glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST); checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST)"); break; case WINED3DTEXF_LINEAR: glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)"); break; default: WARN("Unexpected filter type %d, setting to GL_NICEST\n", FilterType); glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)"); } LEAVE_GL(); context_release(context); } This->baseTexture.filterType = FilterType; TRACE("(%p) :\n", This); return WINED3D_OK; }
static void wined3d_volume_free_pbo(struct wined3d_volume *volume) { struct wined3d_context *context = context_acquire(volume->resource.device, NULL); const struct wined3d_gl_info *gl_info = context->gl_info; TRACE("Deleting PBO %u belonging to volume %p.\n", volume->pbo, volume); GL_EXTCALL(glDeleteBuffersARB(1, &volume->pbo)); checkGLcall("glDeleteBuffersARB"); volume->pbo = 0; context_release(context); }
/* GL locking is done by the caller */ static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type, UINT count, UINT idx_size, const void *idx_data, UINT start_idx) { if (idx_size) { TRACE("(%p) : glElements(%x, %d, ...)\n", iface, primitive_type, count); glDrawElements(primitive_type, count, idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (const char *)idx_data + (idx_size * start_idx)); checkGLcall("glDrawElements"); } else { TRACE("(%p) : glDrawArrays(%#x, %d, %d)\n", iface, primitive_type, start_idx, count); glDrawArrays(primitive_type, start_idx, count); checkGLcall("glDrawArrays"); } }
/* Context activation is done by the caller. */ static void wined3d_volume_allocate_texture(const struct wined3d_volume *volume, const struct wined3d_context *context, BOOL srgb) { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, volume->texture_level, srgb ? format->glGammaInternal : format->glInternal, volume->resource.width, volume->resource.height, volume->resource.depth, 0, format->glFormat, format->glType, NULL)); checkGLcall("glTexImage3D"); }
static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query) { struct wined3d_occlusion_query *oq = query->extendedData; struct wined3d_device *device = query->device; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_context *context; GLuint available; GLuint samples; BOOL ret; if (oq->context->tid != GetCurrentThreadId()) { FIXME("%p Wrong thread, returning 1.\n", query); oq->samples = 1; return TRUE; } context = context_acquire(device, context_get_rt_surface(oq->context)); GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available)); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT_AVAILABLE)"); TRACE("available %#x.\n", available); if (available) { GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT, &samples)); checkGLcall("glGetQueryObjectuiv(GL_QUERY_RESULT)"); TRACE("Returning %d samples.\n", samples); oq->samples = samples; ret = TRUE; } else { ret = FALSE; } context_release(context); return ret; }
/* Context activation is done by the caller. */ static void wined3d_volume_prepare_pbo(struct wined3d_volume *volume, struct wined3d_context *context) { const struct wined3d_gl_info *gl_info = context->gl_info; if (volume->pbo) return; GL_EXTCALL(glGenBuffersARB(1, &volume->pbo)); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->pbo)); GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, volume->resource.size, NULL, GL_STREAM_DRAW_ARB)); GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); checkGLcall("Create PBO"); TRACE("Created PBO %u for volume %p.\n", volume->pbo, volume); }
void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view, unsigned int value) { const struct wined3d_gl_info *gl_info; struct wined3d_context *context; if (!view->counter_bo) return; context = context_acquire(view->resource->device, NULL, 0); gl_info = context->gl_info; GL_EXTCALL(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, view->counter_bo)); GL_EXTCALL(glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(value), &value)); checkGLcall("set atomic counter"); context_release(context); }