void WINAPI NineBaseTexture9_GenerateMipSubLevels( struct NineBaseTexture9 *This ) { struct pipe_resource *resource = This->base.resource; unsigned base_level = 0; unsigned last_level = This->base.info.last_level - This->lod; unsigned first_layer = 0; unsigned last_layer; unsigned filter = This->mipfilter == D3DTEXF_POINT ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; DBG("This=%p\n", This); if (This->base.pool == D3DPOOL_MANAGED) NineBaseTexture9_UploadSelf(This); if (!This->dirty_mip) return; if (This->lod) { ERR("AUTOGENMIPMAP if level 0 is not resident not supported yet !\n"); return; } if (!This->view[0]) NineBaseTexture9_UpdateSamplerView(This, 0); last_layer = util_max_layer(This->view[0]->texture, base_level); util_gen_mipmap(This->pipe, resource, resource->format, base_level, last_level, first_layer, last_layer, filter); This->dirty_mip = FALSE; NineDevice9_RestoreNonCSOState(This->base.base.device, ~0x3); }
static INLINE HRESULT present( struct NineSwapChain9 *This, const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion, DWORD dwFlags ) { struct NineDevice9 *device = This->base.device; struct pipe_resource *resource; HRESULT hr; RGNDATA *rgndata; RECT rect; struct pipe_blit_info blit; /* get a real backbuffer handle from the windowing system */ hr = This->actx->resource_from_present(This->actx, This->screen, This->present, hDestWindowOverride, pDestRect, &rect, &rgndata, &resource); if (FAILED(hr)) { return hr; } else if (hr == D3DOK_WINDOW_OCCLUDED) { /* if we present, nothing will show, so don't present */ return D3D_OK; } DBG(">>>\npresent: This=%p pSourceRect=%p pDestRect=%p " "pDirtyRegion=%p rgndata=%p\n", This, pSourceRect, pDestRect, pDirtyRegion, rgndata); if (pSourceRect) DBG("pSourceRect = (%u..%u)x(%u..%u)\n", pSourceRect->left, pSourceRect->right, pSourceRect->top, pSourceRect->bottom); if (pDestRect) DBG("pDestRect = (%u..%u)x(%u..%u)\n", pDestRect->left, pDestRect->right, pDestRect->top, pDestRect->bottom); if (rgndata) { /* TODO */ blit.dst.resource = NULL; } else { struct pipe_surface *suf = NineSurface9_GetSurface(This->buffers[0], 0); blit.dst.resource = resource; blit.dst.level = 0; blit.dst.format = resource->format; blit.dst.box.z = 0; blit.dst.box.depth = 1; if (pDestRect) { rect_to_pipe_box_xy_only(&blit.dst.box, pDestRect); blit.dst.box.x += rect.left; blit.dst.box.y += rect.top; if (u_box_clip_2d(&blit.dst.box, &blit.dst.box, rect.right, rect.bottom) > 0) { DBG("Dest region clipped.\n"); return D3D_OK; } } else { rect_to_pipe_box_xy_only(&blit.dst.box, &rect); } blit.src.resource = suf->texture; blit.src.level = This->buffers[0]->level; blit.src.format = blit.src.resource->format; blit.src.box.z = 0; blit.src.box.depth = 1; if (pSourceRect) { rect_to_pipe_box_xy_only(&blit.src.box, pSourceRect); u_box_clip_2d(&blit.src.box, &blit.src.box, suf->width, suf->height); } else { blit.src.box.x = 0; blit.src.box.y = 0; blit.src.box.width = suf->width; blit.src.box.height = suf->height; } blit.mask = PIPE_MASK_RGBA; blit.filter = PIPE_TEX_FILTER_NEAREST; blit.scissor_enable = FALSE; blit.alpha_blend = FALSE; /* blit (and possibly stretch/convert) pixels from This->buffers[0] to * emusurf using u_blit. Windows appears to use NEAREST */ DBG("Blitting (%u..%u)x(%u..%u) to (%u..%u)x(%u..%u).\n", blit.src.box.x, blit.src.box.x + blit.src.box.width, blit.src.box.y, blit.src.box.y + blit.src.box.height, blit.dst.box.x, blit.dst.box.x + blit.dst.box.width, blit.dst.box.y, blit.dst.box.y + blit.dst.box.height); This->pipe->blit(This->pipe, &blit); } if (device->cursor.software && device->cursor.visible && device->cursor.w && blit.dst.resource) { blit.src.resource = device->cursor.image; blit.src.level = 0; blit.src.format = device->cursor.image->format; blit.src.box.x = 0; blit.src.box.y = 0; blit.src.box.width = device->cursor.w; blit.src.box.height = device->cursor.h; ID3DPresent_GetCursorPos(This->present, &device->cursor.pos); /* NOTE: blit messes up when box.x + box.width < 0, fix driver */ blit.dst.box.x = MAX2(device->cursor.pos.x, 0) - device->cursor.hotspot.x; blit.dst.box.y = MAX2(device->cursor.pos.y, 0) - device->cursor.hotspot.y; blit.dst.box.width = blit.src.box.width; blit.dst.box.height = blit.src.box.height; DBG("Blitting cursor(%ux%u) to (%i,%i).\n", blit.src.box.width, blit.src.box.height, blit.dst.box.x, blit.dst.box.y); blit.alpha_blend = TRUE; This->pipe->blit(This->pipe, &blit); } if (device->hud && resource) { hud_draw(device->hud, resource); /* XXX: no offset */ /* HUD doesn't clobber stipple */ NineDevice9_RestoreNonCSOState(device, ~0x2); } This->pipe->flush(This->pipe, NULL, PIPE_FLUSH_END_OF_FRAME); /* really present the frame */ hr = ID3DPresent_Present(This->present, dwFlags); pipe_resource_reference(&resource, NULL); if (FAILED(hr)) { return hr; } return D3D_OK; }