1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#include "device9.h" 24bf215546Sopenharmony_ci#include "stateblock9.h" 25bf215546Sopenharmony_ci#include "surface9.h" 26bf215546Sopenharmony_ci#include "swapchain9.h" 27bf215546Sopenharmony_ci#include "swapchain9ex.h" 28bf215546Sopenharmony_ci#include "indexbuffer9.h" 29bf215546Sopenharmony_ci#include "vertexbuffer9.h" 30bf215546Sopenharmony_ci#include "vertexdeclaration9.h" 31bf215546Sopenharmony_ci#include "vertexshader9.h" 32bf215546Sopenharmony_ci#include "pixelshader9.h" 33bf215546Sopenharmony_ci#include "query9.h" 34bf215546Sopenharmony_ci#include "texture9.h" 35bf215546Sopenharmony_ci#include "cubetexture9.h" 36bf215546Sopenharmony_ci#include "volumetexture9.h" 37bf215546Sopenharmony_ci#include "nine_buffer_upload.h" 38bf215546Sopenharmony_ci#include "nine_helpers.h" 39bf215546Sopenharmony_ci#include "nine_memory_helper.h" 40bf215546Sopenharmony_ci#include "nine_pipe.h" 41bf215546Sopenharmony_ci#include "nine_ff.h" 42bf215546Sopenharmony_ci#include "nine_dump.h" 43bf215546Sopenharmony_ci#include "nine_limits.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#include "pipe/p_screen.h" 46bf215546Sopenharmony_ci#include "pipe/p_context.h" 47bf215546Sopenharmony_ci#include "pipe/p_config.h" 48bf215546Sopenharmony_ci#include "util/macros.h" 49bf215546Sopenharmony_ci#include "util/u_math.h" 50bf215546Sopenharmony_ci#include "util/u_inlines.h" 51bf215546Sopenharmony_ci#include "util/u_hash_table.h" 52bf215546Sopenharmony_ci#include "util/format/u_format.h" 53bf215546Sopenharmony_ci#include "util/u_surface.h" 54bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 55bf215546Sopenharmony_ci#include "hud/hud_context.h" 56bf215546Sopenharmony_ci#include "compiler/glsl_types.h" 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci#include "cso_cache/cso_context.h" 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci#define DBG_CHANNEL DBG_DEVICE 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci#if defined(PIPE_CC_GCC) && (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_cistatic void nine_setup_fpu() 65bf215546Sopenharmony_ci{ 66bf215546Sopenharmony_ci uint16_t c; 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci __asm__ __volatile__ ("fnstcw %0" : "=m" (*&c)); 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci /* clear the control word */ 71bf215546Sopenharmony_ci c &= 0xF0C0; 72bf215546Sopenharmony_ci /* d3d9 doc/wine tests: mask all exceptions, use single-precision 73bf215546Sopenharmony_ci * and round to nearest */ 74bf215546Sopenharmony_ci c |= 0x003F; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci __asm__ __volatile__ ("fldcw %0" : : "m" (*&c)); 77bf215546Sopenharmony_ci} 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_cistatic void nine_setup_set_fpu(uint16_t val) 80bf215546Sopenharmony_ci{ 81bf215546Sopenharmony_ci __asm__ __volatile__ ("fldcw %0" : : "m" (*&val)); 82bf215546Sopenharmony_ci} 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_cistatic uint16_t nine_setup_get_fpu() 85bf215546Sopenharmony_ci{ 86bf215546Sopenharmony_ci uint16_t c; 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci __asm__ __volatile__ ("fnstcw %0" : "=m" (*&c)); 89bf215546Sopenharmony_ci return c; 90bf215546Sopenharmony_ci} 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci#else 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_cistatic void nine_setup_fpu(void) 95bf215546Sopenharmony_ci{ 96bf215546Sopenharmony_ci WARN_ONCE("FPU setup not supported on non-x86 platforms\n"); 97bf215546Sopenharmony_ci} 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_cistatic void nine_setup_set_fpu(UNUSED uint16_t val) 100bf215546Sopenharmony_ci{ 101bf215546Sopenharmony_ci WARN_ONCE("FPU setup not supported on non-x86 platforms\n"); 102bf215546Sopenharmony_ci} 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_cistatic uint16_t nine_setup_get_fpu() 105bf215546Sopenharmony_ci{ 106bf215546Sopenharmony_ci WARN_ONCE("FPU setup not supported on non-x86 platforms\n"); 107bf215546Sopenharmony_ci return 0; 108bf215546Sopenharmony_ci} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci#endif 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_cistruct pipe_resource * 113bf215546Sopenharmony_cinine_resource_create_with_retry( struct NineDevice9 *This, 114bf215546Sopenharmony_ci struct pipe_screen *screen, 115bf215546Sopenharmony_ci const struct pipe_resource *templat ) 116bf215546Sopenharmony_ci{ 117bf215546Sopenharmony_ci struct pipe_resource *res; 118bf215546Sopenharmony_ci res = screen->resource_create(screen, templat); 119bf215546Sopenharmony_ci if (res) 120bf215546Sopenharmony_ci return res; 121bf215546Sopenharmony_ci /* Allocation failed, retry after freeing some resources 122bf215546Sopenharmony_ci * Note: Shouldn't be called from the worker thread */ 123bf215546Sopenharmony_ci if (!This) 124bf215546Sopenharmony_ci return NULL; 125bf215546Sopenharmony_ci /* Evict resources we can evict */ 126bf215546Sopenharmony_ci NineDevice9_EvictManagedResourcesInternal(This); 127bf215546Sopenharmony_ci /* Execute anything pending, such that some 128bf215546Sopenharmony_ci * deleted resources can be actually freed */ 129bf215546Sopenharmony_ci nine_csmt_process(This); 130bf215546Sopenharmony_ci /* We could also finish the context, if needed */ 131bf215546Sopenharmony_ci return screen->resource_create(screen, templat); 132bf215546Sopenharmony_ci} 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_civoid 135bf215546Sopenharmony_ciNineDevice9_SetDefaultState( struct NineDevice9 *This, boolean is_reset ) 136bf215546Sopenharmony_ci{ 137bf215546Sopenharmony_ci struct NineSurface9 *refSurf = NULL; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci DBG("This=%p is_reset=%d\n", This, (int) is_reset); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci assert(!This->is_recording); 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci nine_state_set_defaults(This, &This->caps, is_reset); 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci refSurf = This->swapchains[0]->buffers[0]; 146bf215546Sopenharmony_ci assert(refSurf); 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci This->state.viewport.X = 0; 149bf215546Sopenharmony_ci This->state.viewport.Y = 0; 150bf215546Sopenharmony_ci This->state.viewport.Width = refSurf->desc.Width; 151bf215546Sopenharmony_ci This->state.viewport.Height = refSurf->desc.Height; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci nine_context_set_viewport(This, &This->state.viewport); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci This->state.scissor.minx = 0; 156bf215546Sopenharmony_ci This->state.scissor.miny = 0; 157bf215546Sopenharmony_ci This->state.scissor.maxx = refSurf->desc.Width; 158bf215546Sopenharmony_ci This->state.scissor.maxy = refSurf->desc.Height; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci nine_context_set_scissor(This, &This->state.scissor); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci if (This->nswapchains && This->swapchains[0]->params.EnableAutoDepthStencil) { 163bf215546Sopenharmony_ci nine_context_set_render_state(This, D3DRS_ZENABLE, TRUE); 164bf215546Sopenharmony_ci This->state.rs_advertised[D3DRS_ZENABLE] = TRUE; 165bf215546Sopenharmony_ci } 166bf215546Sopenharmony_ci if (This->state.rs_advertised[D3DRS_ZENABLE]) 167bf215546Sopenharmony_ci NineDevice9_SetDepthStencilSurface( 168bf215546Sopenharmony_ci This, (IDirect3DSurface9 *)This->swapchains[0]->zsbuf); 169bf215546Sopenharmony_ci} 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci#define GET_PCAP(n) pScreen->get_param(pScreen, PIPE_CAP_##n) 172bf215546Sopenharmony_ciHRESULT 173bf215546Sopenharmony_ciNineDevice9_ctor( struct NineDevice9 *This, 174bf215546Sopenharmony_ci struct NineUnknownParams *pParams, 175bf215546Sopenharmony_ci struct pipe_screen *pScreen, 176bf215546Sopenharmony_ci D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, 177bf215546Sopenharmony_ci D3DCAPS9 *pCaps, 178bf215546Sopenharmony_ci D3DPRESENT_PARAMETERS *pPresentationParameters, 179bf215546Sopenharmony_ci IDirect3D9 *pD3D9, 180bf215546Sopenharmony_ci ID3DPresentGroup *pPresentationGroup, 181bf215546Sopenharmony_ci struct d3dadapter9_context *pCTX, 182bf215546Sopenharmony_ci boolean ex, 183bf215546Sopenharmony_ci D3DDISPLAYMODEEX *pFullscreenDisplayMode, 184bf215546Sopenharmony_ci int minorVersionNum ) 185bf215546Sopenharmony_ci{ 186bf215546Sopenharmony_ci unsigned i; 187bf215546Sopenharmony_ci uint16_t fpu_cw = 0; 188bf215546Sopenharmony_ci HRESULT hr = NineUnknown_ctor(&This->base, pParams); 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p pPresentationParameters=%p " 191bf215546Sopenharmony_ci "pD3D9=%p pPresentationGroup=%p pCTX=%p ex=%d pFullscreenDisplayMode=%p\n", 192bf215546Sopenharmony_ci This, pParams, pScreen, pCreationParameters, pCaps, pPresentationParameters, pD3D9, 193bf215546Sopenharmony_ci pPresentationGroup, pCTX, (int) ex, pFullscreenDisplayMode); 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci if (FAILED(hr)) { return hr; } 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci /* NIR shaders need to use GLSL types so let's initialize them here */ 198bf215546Sopenharmony_ci glsl_type_singleton_init_or_ref(); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci list_inithead(&This->update_buffers); 201bf215546Sopenharmony_ci list_inithead(&This->update_textures); 202bf215546Sopenharmony_ci list_inithead(&This->managed_buffers); 203bf215546Sopenharmony_ci list_inithead(&This->managed_textures); 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci This->screen = pScreen; 206bf215546Sopenharmony_ci This->screen_sw = pCTX->ref; 207bf215546Sopenharmony_ci This->caps = *pCaps; 208bf215546Sopenharmony_ci This->d3d9 = pD3D9; 209bf215546Sopenharmony_ci This->params = *pCreationParameters; 210bf215546Sopenharmony_ci This->ex = ex; 211bf215546Sopenharmony_ci This->present = pPresentationGroup; 212bf215546Sopenharmony_ci This->minor_version_num = minorVersionNum; 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci /* Ex */ 215bf215546Sopenharmony_ci This->gpu_priority = 0; 216bf215546Sopenharmony_ci This->max_frame_latency = 3; 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci IDirect3D9_AddRef(This->d3d9); 219bf215546Sopenharmony_ci ID3DPresentGroup_AddRef(This->present); 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci if (!(This->params.BehaviorFlags & D3DCREATE_FPU_PRESERVE)) { 222bf215546Sopenharmony_ci nine_setup_fpu(); 223bf215546Sopenharmony_ci } else { 224bf215546Sopenharmony_ci /* Software renderer initialization needs exceptions masked */ 225bf215546Sopenharmony_ci fpu_cw = nine_setup_get_fpu(); 226bf215546Sopenharmony_ci nine_setup_set_fpu(fpu_cw | 0x007f); 227bf215546Sopenharmony_ci } 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci if (This->params.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) { 230bf215546Sopenharmony_ci DBG("Application asked full Software Vertex Processing.\n"); 231bf215546Sopenharmony_ci This->swvp = true; 232bf215546Sopenharmony_ci This->may_swvp = true; 233bf215546Sopenharmony_ci } else 234bf215546Sopenharmony_ci This->swvp = false; 235bf215546Sopenharmony_ci if (This->params.BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) { 236bf215546Sopenharmony_ci DBG("Application asked mixed Software Vertex Processing.\n"); 237bf215546Sopenharmony_ci This->may_swvp = true; 238bf215546Sopenharmony_ci } 239bf215546Sopenharmony_ci This->context.swvp = This->swvp; 240bf215546Sopenharmony_ci /* TODO: check if swvp is resetted by device Resets */ 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci if (This->may_swvp && 243bf215546Sopenharmony_ci (This->screen->get_shader_param(This->screen, PIPE_SHADER_VERTEX, 244bf215546Sopenharmony_ci PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE) 245bf215546Sopenharmony_ci < (NINE_MAX_CONST_F_SWVP/2) * sizeof(float[4]) || 246bf215546Sopenharmony_ci This->screen->get_shader_param(This->screen, PIPE_SHADER_VERTEX, 247bf215546Sopenharmony_ci PIPE_SHADER_CAP_MAX_CONST_BUFFERS) < 5)) { 248bf215546Sopenharmony_ci /* Note: We just go on, some apps never use the abilities of 249bf215546Sopenharmony_ci * swvp, and just set more constants than allowed at init. 250bf215546Sopenharmony_ci * Only cards we support that are affected are the r500 */ 251bf215546Sopenharmony_ci WARN("Card unable to handle Software Vertex Processing. Game may fail\n"); 252bf215546Sopenharmony_ci } 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci /* When may_swvp, SetConstant* limits are different */ 255bf215546Sopenharmony_ci if (This->may_swvp) 256bf215546Sopenharmony_ci This->caps.MaxVertexShaderConst = NINE_MAX_CONST_F_SWVP; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci This->pure = !!(This->params.BehaviorFlags & D3DCREATE_PUREDEVICE); 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci This->context.pipe = This->screen->context_create(This->screen, NULL, PIPE_CONTEXT_PREFER_THREADED); 261bf215546Sopenharmony_ci This->pipe_secondary = This->screen->context_create(This->screen, NULL, 0); 262bf215546Sopenharmony_ci if (!This->context.pipe || !This->pipe_secondary) { return E_OUTOFMEMORY; } /* guess */ 263bf215546Sopenharmony_ci This->pipe_sw = This->screen_sw->context_create(This->screen_sw, NULL, PIPE_CONTEXT_PREFER_THREADED); 264bf215546Sopenharmony_ci if (!This->pipe_sw) { return E_OUTOFMEMORY; } 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci This->context.cso = cso_create_context(This->context.pipe, CSO_NO_USER_VERTEX_BUFFERS); 267bf215546Sopenharmony_ci if (!This->context.cso) { return E_OUTOFMEMORY; } /* also a guess */ 268bf215546Sopenharmony_ci This->cso_sw = cso_create_context(This->pipe_sw, 0); 269bf215546Sopenharmony_ci if (!This->cso_sw) { return E_OUTOFMEMORY; } 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* Create first, it messes up our state. */ 272bf215546Sopenharmony_ci This->hud = hud_create(This->context.cso, NULL, NULL); /* NULL result is fine */ 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci This->allocator = nine_allocator_create(This, pCTX->memfd_virtualsizelimit); 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci /* Available memory counter. Updated only for allocations with this device 277bf215546Sopenharmony_ci * instance. This is the Win 7 behavior. 278bf215546Sopenharmony_ci * Win XP shares this counter across multiple devices. */ 279bf215546Sopenharmony_ci This->available_texture_mem = This->screen->get_param(This->screen, PIPE_CAP_VIDEO_MEMORY); 280bf215546Sopenharmony_ci This->available_texture_mem = (pCTX->override_vram_size >= 0) ? 281bf215546Sopenharmony_ci (long long)pCTX->override_vram_size : This->available_texture_mem; 282bf215546Sopenharmony_ci This->available_texture_mem <<= 20; 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci /* We cap texture memory usage to 95% of what is reported free initially 285bf215546Sopenharmony_ci * This helps get closer Win behaviour. For example VertexBuffer allocation 286bf215546Sopenharmony_ci * still succeeds when texture allocation fails. */ 287bf215546Sopenharmony_ci This->available_texture_limit = This->available_texture_mem * 5LL / 100LL; 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci This->frame_count = 0; /* Used to check if events occur the same frame */ 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci /* create implicit swapchains */ 292bf215546Sopenharmony_ci This->nswapchains = ID3DPresentGroup_GetMultiheadCount(This->present); 293bf215546Sopenharmony_ci This->swapchains = CALLOC(This->nswapchains, 294bf215546Sopenharmony_ci sizeof(struct NineSwapChain9 *)); 295bf215546Sopenharmony_ci if (!This->swapchains) { return E_OUTOFMEMORY; } 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci for (i = 0; i < This->nswapchains; ++i) { 298bf215546Sopenharmony_ci ID3DPresent *present; 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci hr = ID3DPresentGroup_GetPresent(This->present, i, &present); 301bf215546Sopenharmony_ci if (FAILED(hr)) 302bf215546Sopenharmony_ci return hr; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci if (ex) { 305bf215546Sopenharmony_ci D3DDISPLAYMODEEX *mode = NULL; 306bf215546Sopenharmony_ci struct NineSwapChain9Ex **ret = 307bf215546Sopenharmony_ci (struct NineSwapChain9Ex **)&This->swapchains[i]; 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci if (pFullscreenDisplayMode) mode = &(pFullscreenDisplayMode[i]); 310bf215546Sopenharmony_ci /* when this is a Device9Ex, it should create SwapChain9Exs */ 311bf215546Sopenharmony_ci hr = NineSwapChain9Ex_new(This, TRUE, present, 312bf215546Sopenharmony_ci &pPresentationParameters[i], pCTX, 313bf215546Sopenharmony_ci This->params.hFocusWindow, mode, ret); 314bf215546Sopenharmony_ci } else { 315bf215546Sopenharmony_ci hr = NineSwapChain9_new(This, TRUE, present, 316bf215546Sopenharmony_ci &pPresentationParameters[i], pCTX, 317bf215546Sopenharmony_ci This->params.hFocusWindow, 318bf215546Sopenharmony_ci &This->swapchains[i]); 319bf215546Sopenharmony_ci } 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci ID3DPresent_Release(present); 322bf215546Sopenharmony_ci if (FAILED(hr)) 323bf215546Sopenharmony_ci return hr; 324bf215546Sopenharmony_ci NineUnknown_ConvertRefToBind(NineUnknown(This->swapchains[i])); 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci hr = NineSwapChain9_GetBackBuffer(This->swapchains[i], 0, 327bf215546Sopenharmony_ci D3DBACKBUFFER_TYPE_MONO, 328bf215546Sopenharmony_ci (IDirect3DSurface9 **) 329bf215546Sopenharmony_ci &This->state.rt[i]); 330bf215546Sopenharmony_ci if (FAILED(hr)) 331bf215546Sopenharmony_ci return hr; 332bf215546Sopenharmony_ci NineUnknown_ConvertRefToBind(NineUnknown(This->state.rt[i])); 333bf215546Sopenharmony_ci nine_bind(&This->context.rt[i], This->state.rt[i]); 334bf215546Sopenharmony_ci } 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci /* Initialize CSMT */ 337bf215546Sopenharmony_ci /* r600, radeonsi and iris are thread safe. */ 338bf215546Sopenharmony_ci if (pCTX->csmt_force == 1) 339bf215546Sopenharmony_ci This->csmt_active = true; 340bf215546Sopenharmony_ci else if (pCTX->csmt_force == 0) 341bf215546Sopenharmony_ci This->csmt_active = false; 342bf215546Sopenharmony_ci else if (strstr(pScreen->get_name(pScreen), "AMD") != NULL) 343bf215546Sopenharmony_ci This->csmt_active = true; 344bf215546Sopenharmony_ci else if (strstr(pScreen->get_name(pScreen), "Intel") != NULL) 345bf215546Sopenharmony_ci This->csmt_active = true; 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci /* We rely on u_upload_mgr using persistent coherent buffers (which don't 348bf215546Sopenharmony_ci * require flush to work in multi-pipe_context scenario) for vertex and 349bf215546Sopenharmony_ci * index buffers */ 350bf215546Sopenharmony_ci if (!GET_PCAP(BUFFER_MAP_PERSISTENT_COHERENT)) 351bf215546Sopenharmony_ci This->csmt_active = false; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci if (This->csmt_active) { 354bf215546Sopenharmony_ci This->csmt_ctx = nine_csmt_create(This); 355bf215546Sopenharmony_ci if (!This->csmt_ctx) 356bf215546Sopenharmony_ci return E_OUTOFMEMORY; 357bf215546Sopenharmony_ci } 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci if (This->csmt_active) 360bf215546Sopenharmony_ci DBG("\033[1;32mCSMT is active\033[0m\n"); 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci This->workarounds.dynamic_texture_workaround = pCTX->dynamic_texture_workaround; 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci /* Due to the pb_cache, in some cases the buffer_upload path can increase GTT usage/virtual memory. 365bf215546Sopenharmony_ci * As the performance gain is negligible when csmt is off, disable it in this case. 366bf215546Sopenharmony_ci * That way csmt_force=0 can be used as a workaround to reduce GTT usage/virtual memory. */ 367bf215546Sopenharmony_ci This->buffer_upload = This->csmt_active ? nine_upload_create(This->pipe_secondary, 4 * 1024 * 1024, 4) : NULL; 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci /* Initialize a dummy VBO to be used when a vertex declaration does not 370bf215546Sopenharmony_ci * specify all the inputs needed by vertex shader, on win default behavior 371bf215546Sopenharmony_ci * is to pass 0,0,0,0 to the shader */ 372bf215546Sopenharmony_ci { 373bf215546Sopenharmony_ci struct pipe_transfer *transfer; 374bf215546Sopenharmony_ci struct pipe_resource tmpl; 375bf215546Sopenharmony_ci struct pipe_box box; 376bf215546Sopenharmony_ci unsigned char *data; 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci memset(&tmpl, 0, sizeof(tmpl)); 379bf215546Sopenharmony_ci tmpl.target = PIPE_BUFFER; 380bf215546Sopenharmony_ci tmpl.format = PIPE_FORMAT_R8_UNORM; 381bf215546Sopenharmony_ci tmpl.width0 = 16; /* 4 floats */ 382bf215546Sopenharmony_ci tmpl.height0 = 1; 383bf215546Sopenharmony_ci tmpl.depth0 = 1; 384bf215546Sopenharmony_ci tmpl.array_size = 1; 385bf215546Sopenharmony_ci tmpl.last_level = 0; 386bf215546Sopenharmony_ci tmpl.nr_samples = 0; 387bf215546Sopenharmony_ci tmpl.usage = PIPE_USAGE_DEFAULT; 388bf215546Sopenharmony_ci tmpl.bind = PIPE_BIND_VERTEX_BUFFER; 389bf215546Sopenharmony_ci tmpl.flags = 0; 390bf215546Sopenharmony_ci This->dummy_vbo = pScreen->resource_create(pScreen, &tmpl); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci if (!This->dummy_vbo) 393bf215546Sopenharmony_ci return D3DERR_OUTOFVIDEOMEMORY; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci u_box_1d(0, 16, &box); 396bf215546Sopenharmony_ci data = This->context.pipe->buffer_map(This->context.pipe, This->dummy_vbo, 0, 397bf215546Sopenharmony_ci PIPE_MAP_WRITE | 398bf215546Sopenharmony_ci PIPE_MAP_DISCARD_WHOLE_RESOURCE, 399bf215546Sopenharmony_ci &box, &transfer); 400bf215546Sopenharmony_ci assert(data); 401bf215546Sopenharmony_ci assert(transfer); 402bf215546Sopenharmony_ci memset(data, 0, 16); 403bf215546Sopenharmony_ci This->context.pipe->buffer_unmap(This->context.pipe, transfer); 404bf215546Sopenharmony_ci } 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci This->cursor.software = FALSE; 407bf215546Sopenharmony_ci This->cursor.hotspot.x = -1; 408bf215546Sopenharmony_ci This->cursor.hotspot.y = -1; 409bf215546Sopenharmony_ci This->cursor.w = This->cursor.h = 0; 410bf215546Sopenharmony_ci This->cursor.visible = FALSE; 411bf215546Sopenharmony_ci if (ID3DPresent_GetCursorPos(This->swapchains[0]->present, &This->cursor.pos) != S_OK) { 412bf215546Sopenharmony_ci This->cursor.pos.x = 0; 413bf215546Sopenharmony_ci This->cursor.pos.y = 0; 414bf215546Sopenharmony_ci } 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci { 417bf215546Sopenharmony_ci struct pipe_resource tmpl; 418bf215546Sopenharmony_ci memset(&tmpl, 0, sizeof(tmpl)); 419bf215546Sopenharmony_ci tmpl.target = PIPE_TEXTURE_2D; 420bf215546Sopenharmony_ci tmpl.format = PIPE_FORMAT_R8G8B8A8_UNORM; 421bf215546Sopenharmony_ci tmpl.width0 = 64; 422bf215546Sopenharmony_ci tmpl.height0 = 64; 423bf215546Sopenharmony_ci tmpl.depth0 = 1; 424bf215546Sopenharmony_ci tmpl.array_size = 1; 425bf215546Sopenharmony_ci tmpl.last_level = 0; 426bf215546Sopenharmony_ci tmpl.nr_samples = 0; 427bf215546Sopenharmony_ci tmpl.usage = PIPE_USAGE_DEFAULT; 428bf215546Sopenharmony_ci tmpl.bind = PIPE_BIND_CURSOR | PIPE_BIND_SAMPLER_VIEW; 429bf215546Sopenharmony_ci tmpl.flags = 0; 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci This->cursor.image = pScreen->resource_create(pScreen, &tmpl); 432bf215546Sopenharmony_ci if (!This->cursor.image) 433bf215546Sopenharmony_ci return D3DERR_OUTOFVIDEOMEMORY; 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci /* For uploading 32x32 (argb) cursor */ 436bf215546Sopenharmony_ci This->cursor.hw_upload_temp = MALLOC(32 * 4 * 32); 437bf215546Sopenharmony_ci if (!This->cursor.hw_upload_temp) 438bf215546Sopenharmony_ci return D3DERR_OUTOFVIDEOMEMORY; 439bf215546Sopenharmony_ci } 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci /* Create constant buffers. */ 442bf215546Sopenharmony_ci { 443bf215546Sopenharmony_ci unsigned max_const_vs, max_const_ps; 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci /* vs 3.0: >= 256 float constants, but for cards with exactly 256 slots, 446bf215546Sopenharmony_ci * we have to take in some more slots for int and bool*/ 447bf215546Sopenharmony_ci max_const_vs = _min(pScreen->get_shader_param(pScreen, PIPE_SHADER_VERTEX, 448bf215546Sopenharmony_ci PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE) / 449bf215546Sopenharmony_ci sizeof(float[4]), 450bf215546Sopenharmony_ci NINE_MAX_CONST_ALL); 451bf215546Sopenharmony_ci /* ps 3.0: 224 float constants. All cards supported support at least 452bf215546Sopenharmony_ci * 256 constants for ps */ 453bf215546Sopenharmony_ci max_const_ps = NINE_MAX_CONST_F_PS3 + (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4); 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_ci This->max_vs_const_f = max_const_vs - 456bf215546Sopenharmony_ci (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4); 457bf215546Sopenharmony_ci This->max_ps_const_f = max_const_ps - 458bf215546Sopenharmony_ci (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4); 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci This->vs_const_size = max_const_vs * sizeof(float[4]); 461bf215546Sopenharmony_ci This->ps_const_size = max_const_ps * sizeof(float[4]); 462bf215546Sopenharmony_ci /* Include space for I,B constants for user constbuf. */ 463bf215546Sopenharmony_ci if (This->may_swvp) { 464bf215546Sopenharmony_ci This->state.vs_const_f = CALLOC(NINE_MAX_CONST_F_SWVP * sizeof(float[4]),1); 465bf215546Sopenharmony_ci This->context.vs_const_f_swvp = CALLOC(NINE_MAX_CONST_F_SWVP * sizeof(float[4]),1); 466bf215546Sopenharmony_ci if (!This->context.vs_const_f_swvp) 467bf215546Sopenharmony_ci return E_OUTOFMEMORY; 468bf215546Sopenharmony_ci This->state.vs_lconstf_temp = CALLOC(NINE_MAX_CONST_F_SWVP * sizeof(float[4]),1); 469bf215546Sopenharmony_ci This->context.vs_lconstf_temp = CALLOC(NINE_MAX_CONST_F_SWVP * sizeof(float[4]),1); 470bf215546Sopenharmony_ci This->state.vs_const_i = CALLOC(NINE_MAX_CONST_I_SWVP * sizeof(int[4]), 1); 471bf215546Sopenharmony_ci This->context.vs_const_i = CALLOC(NINE_MAX_CONST_I_SWVP * sizeof(int[4]), 1); 472bf215546Sopenharmony_ci This->state.vs_const_b = CALLOC(NINE_MAX_CONST_B_SWVP * sizeof(BOOL), 1); 473bf215546Sopenharmony_ci This->context.vs_const_b = CALLOC(NINE_MAX_CONST_B_SWVP * sizeof(BOOL), 1); 474bf215546Sopenharmony_ci } else { 475bf215546Sopenharmony_ci This->state.vs_const_f = CALLOC(NINE_MAX_CONST_F * sizeof(float[4]), 1); 476bf215546Sopenharmony_ci This->context.vs_const_f_swvp = NULL; 477bf215546Sopenharmony_ci This->state.vs_lconstf_temp = CALLOC(This->vs_const_size,1); 478bf215546Sopenharmony_ci This->context.vs_lconstf_temp = CALLOC(This->vs_const_size,1); 479bf215546Sopenharmony_ci This->state.vs_const_i = CALLOC(NINE_MAX_CONST_I * sizeof(int[4]), 1); 480bf215546Sopenharmony_ci This->context.vs_const_i = CALLOC(NINE_MAX_CONST_I * sizeof(int[4]), 1); 481bf215546Sopenharmony_ci This->state.vs_const_b = CALLOC(NINE_MAX_CONST_B * sizeof(BOOL), 1); 482bf215546Sopenharmony_ci This->context.vs_const_b = CALLOC(NINE_MAX_CONST_B * sizeof(BOOL), 1); 483bf215546Sopenharmony_ci } 484bf215546Sopenharmony_ci This->context.vs_const_f = CALLOC(This->vs_const_size, 1); 485bf215546Sopenharmony_ci This->state.ps_const_f = CALLOC(This->ps_const_size, 1); 486bf215546Sopenharmony_ci This->context.ps_const_f = CALLOC(This->ps_const_size, 1); 487bf215546Sopenharmony_ci This->context.ps_lconstf_temp = CALLOC(This->ps_const_size,1); 488bf215546Sopenharmony_ci if (!This->state.vs_const_f || !This->context.vs_const_f || 489bf215546Sopenharmony_ci !This->state.ps_const_f || !This->context.ps_const_f || 490bf215546Sopenharmony_ci !This->state.vs_lconstf_temp || !This->context.vs_lconstf_temp || 491bf215546Sopenharmony_ci !This->context.ps_lconstf_temp || 492bf215546Sopenharmony_ci !This->state.vs_const_i || !This->context.vs_const_i || 493bf215546Sopenharmony_ci !This->state.vs_const_b || !This->context.vs_const_b) 494bf215546Sopenharmony_ci return E_OUTOFMEMORY; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci if (strstr(pScreen->get_name(pScreen), "AMD") || 497bf215546Sopenharmony_ci strstr(pScreen->get_name(pScreen), "ATI")) { 498bf215546Sopenharmony_ci This->driver_bugs.buggy_barycentrics = TRUE; 499bf215546Sopenharmony_ci } 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci /* allocate dummy texture/sampler for when there are missing ones bound */ 503bf215546Sopenharmony_ci { 504bf215546Sopenharmony_ci struct pipe_resource tmplt; 505bf215546Sopenharmony_ci struct pipe_sampler_view templ; 506bf215546Sopenharmony_ci struct pipe_sampler_state samp; 507bf215546Sopenharmony_ci memset(&tmplt, 0, sizeof(tmplt)); 508bf215546Sopenharmony_ci memset(&samp, 0, sizeof(samp)); 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci tmplt.target = PIPE_TEXTURE_2D; 511bf215546Sopenharmony_ci tmplt.width0 = 1; 512bf215546Sopenharmony_ci tmplt.height0 = 1; 513bf215546Sopenharmony_ci tmplt.depth0 = 1; 514bf215546Sopenharmony_ci tmplt.last_level = 0; 515bf215546Sopenharmony_ci tmplt.array_size = 1; 516bf215546Sopenharmony_ci tmplt.usage = PIPE_USAGE_DEFAULT; 517bf215546Sopenharmony_ci tmplt.flags = 0; 518bf215546Sopenharmony_ci tmplt.format = PIPE_FORMAT_B8G8R8A8_UNORM; 519bf215546Sopenharmony_ci tmplt.bind = PIPE_BIND_SAMPLER_VIEW; 520bf215546Sopenharmony_ci tmplt.nr_samples = 0; 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ci This->dummy_texture = This->screen->resource_create(This->screen, &tmplt); 523bf215546Sopenharmony_ci if (!This->dummy_texture) 524bf215546Sopenharmony_ci return D3DERR_DRIVERINTERNALERROR; 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; 527bf215546Sopenharmony_ci templ.u.tex.first_layer = 0; 528bf215546Sopenharmony_ci templ.u.tex.last_layer = 0; 529bf215546Sopenharmony_ci templ.u.tex.first_level = 0; 530bf215546Sopenharmony_ci templ.u.tex.last_level = 0; 531bf215546Sopenharmony_ci templ.swizzle_r = PIPE_SWIZZLE_0; 532bf215546Sopenharmony_ci templ.swizzle_g = PIPE_SWIZZLE_0; 533bf215546Sopenharmony_ci templ.swizzle_b = PIPE_SWIZZLE_0; 534bf215546Sopenharmony_ci templ.swizzle_a = PIPE_SWIZZLE_1; 535bf215546Sopenharmony_ci templ.target = This->dummy_texture->target; 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci This->dummy_sampler_view = This->context.pipe->create_sampler_view(This->context.pipe, This->dummy_texture, &templ); 538bf215546Sopenharmony_ci if (!This->dummy_sampler_view) 539bf215546Sopenharmony_ci return D3DERR_DRIVERINTERNALERROR; 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci samp.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 542bf215546Sopenharmony_ci samp.max_lod = 15.0f; 543bf215546Sopenharmony_ci samp.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 544bf215546Sopenharmony_ci samp.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 545bf215546Sopenharmony_ci samp.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 546bf215546Sopenharmony_ci samp.min_img_filter = PIPE_TEX_FILTER_NEAREST; 547bf215546Sopenharmony_ci samp.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 548bf215546Sopenharmony_ci samp.compare_mode = PIPE_TEX_COMPARE_NONE; 549bf215546Sopenharmony_ci samp.compare_func = PIPE_FUNC_LEQUAL; 550bf215546Sopenharmony_ci samp.normalized_coords = 1; 551bf215546Sopenharmony_ci samp.seamless_cube_map = 0; 552bf215546Sopenharmony_ci This->dummy_sampler_state = samp; 553bf215546Sopenharmony_ci } 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci /* Allocate upload helper for drivers that suck (from st pov ;). */ 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci This->driver_caps.user_sw_vbufs = This->screen_sw->get_param(This->screen_sw, PIPE_CAP_USER_VERTEX_BUFFERS); 558bf215546Sopenharmony_ci This->vertex_uploader = This->csmt_active ? This->pipe_secondary->stream_uploader : This->context.pipe->stream_uploader; 559bf215546Sopenharmony_ci This->driver_caps.window_space_position_support = GET_PCAP(VS_WINDOW_SPACE_POSITION); 560bf215546Sopenharmony_ci This->driver_caps.vs_integer = pScreen->get_shader_param(pScreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS); 561bf215546Sopenharmony_ci This->driver_caps.ps_integer = pScreen->get_shader_param(pScreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_INTEGERS); 562bf215546Sopenharmony_ci This->driver_caps.offset_units_unscaled = GET_PCAP(POLYGON_OFFSET_UNITS_UNSCALED); 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci This->context.inline_constants = pCTX->shader_inline_constants; 565bf215546Sopenharmony_ci /* Code would be needed when integers are not available to correctly 566bf215546Sopenharmony_ci * handle the conversion of integer constants */ 567bf215546Sopenharmony_ci This->context.inline_constants &= This->driver_caps.vs_integer && This->driver_caps.ps_integer; 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci nine_ff_init(This); /* initialize fixed function code */ 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci NineDevice9_SetDefaultState(This, FALSE); 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci { 574bf215546Sopenharmony_ci struct pipe_poly_stipple stipple; 575bf215546Sopenharmony_ci memset(&stipple, ~0, sizeof(stipple)); 576bf215546Sopenharmony_ci This->context.pipe->set_polygon_stipple(This->context.pipe, &stipple); 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci This->update = &This->state; 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci nine_state_init_sw(This); 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ci ID3DPresentGroup_Release(This->present); 584bf215546Sopenharmony_ci nine_context_update_state(This); /* Some drivers needs states to be initialized */ 585bf215546Sopenharmony_ci nine_csmt_process(This); 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci if (This->params.BehaviorFlags & D3DCREATE_FPU_PRESERVE) 588bf215546Sopenharmony_ci nine_setup_set_fpu(fpu_cw); 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci return D3D_OK; 591bf215546Sopenharmony_ci} 592bf215546Sopenharmony_ci#undef GET_PCAP 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_civoid 595bf215546Sopenharmony_ciNineDevice9_dtor( struct NineDevice9 *This ) 596bf215546Sopenharmony_ci{ 597bf215546Sopenharmony_ci unsigned i; 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci DBG("This=%p\n", This); 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci /* Flush all pending commands to get refcount right, 602bf215546Sopenharmony_ci * and properly release bound objects. It is ok to still 603bf215546Sopenharmony_ci * execute commands while we are in device dtor, because 604bf215546Sopenharmony_ci * we haven't released anything yet. Note that no pending 605bf215546Sopenharmony_ci * command can increase the device refcount. */ 606bf215546Sopenharmony_ci if (This->csmt_active && This->csmt_ctx) { 607bf215546Sopenharmony_ci nine_csmt_process(This); 608bf215546Sopenharmony_ci nine_csmt_destroy(This, This->csmt_ctx); 609bf215546Sopenharmony_ci This->csmt_active = FALSE; 610bf215546Sopenharmony_ci This->csmt_ctx = NULL; 611bf215546Sopenharmony_ci } 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci nine_ff_fini(This); 614bf215546Sopenharmony_ci nine_state_destroy_sw(This); 615bf215546Sopenharmony_ci nine_device_state_clear(This); 616bf215546Sopenharmony_ci nine_context_clear(This); 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci nine_bind(&This->record, NULL); 619bf215546Sopenharmony_ci 620bf215546Sopenharmony_ci pipe_sampler_view_reference(&This->dummy_sampler_view, NULL); 621bf215546Sopenharmony_ci pipe_resource_reference(&This->dummy_texture, NULL); 622bf215546Sopenharmony_ci pipe_resource_reference(&This->dummy_vbo, NULL); 623bf215546Sopenharmony_ci FREE(This->state.vs_const_f); 624bf215546Sopenharmony_ci FREE(This->context.vs_const_f); 625bf215546Sopenharmony_ci FREE(This->state.ps_const_f); 626bf215546Sopenharmony_ci FREE(This->context.ps_const_f); 627bf215546Sopenharmony_ci FREE(This->state.vs_lconstf_temp); 628bf215546Sopenharmony_ci FREE(This->context.vs_lconstf_temp); 629bf215546Sopenharmony_ci FREE(This->context.ps_lconstf_temp); 630bf215546Sopenharmony_ci FREE(This->state.vs_const_i); 631bf215546Sopenharmony_ci FREE(This->context.vs_const_i); 632bf215546Sopenharmony_ci FREE(This->state.vs_const_b); 633bf215546Sopenharmony_ci FREE(This->context.vs_const_b); 634bf215546Sopenharmony_ci FREE(This->context.vs_const_f_swvp); 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_ci pipe_resource_reference(&This->cursor.image, NULL); 637bf215546Sopenharmony_ci FREE(This->cursor.hw_upload_temp); 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_ci if (This->swapchains) { 640bf215546Sopenharmony_ci for (i = 0; i < This->nswapchains; ++i) 641bf215546Sopenharmony_ci if (This->swapchains[i]) 642bf215546Sopenharmony_ci NineUnknown_Unbind(NineUnknown(This->swapchains[i])); 643bf215546Sopenharmony_ci FREE(This->swapchains); 644bf215546Sopenharmony_ci } 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci if (This->buffer_upload) 647bf215546Sopenharmony_ci nine_upload_destroy(This->buffer_upload); 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_ci if (This->allocator) 650bf215546Sopenharmony_ci nine_allocator_destroy(This->allocator); 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci /* Destroy cso first */ 653bf215546Sopenharmony_ci if (This->context.cso) { cso_destroy_context(This->context.cso); } 654bf215546Sopenharmony_ci if (This->cso_sw) { cso_destroy_context(This->cso_sw); } 655bf215546Sopenharmony_ci if (This->context.pipe && This->context.pipe->destroy) { This->context.pipe->destroy(This->context.pipe); } 656bf215546Sopenharmony_ci if (This->pipe_secondary && This->pipe_secondary->destroy) { This->pipe_secondary->destroy(This->pipe_secondary); } 657bf215546Sopenharmony_ci if (This->pipe_sw && This->pipe_sw->destroy) { This->pipe_sw->destroy(This->pipe_sw); } 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci if (This->present) { ID3DPresentGroup_Release(This->present); } 660bf215546Sopenharmony_ci if (This->d3d9) { IDirect3D9_Release(This->d3d9); } 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ci NineUnknown_dtor(&This->base); 663bf215546Sopenharmony_ci glsl_type_singleton_decref(); 664bf215546Sopenharmony_ci} 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_cistruct pipe_screen * 667bf215546Sopenharmony_ciNineDevice9_GetScreen( struct NineDevice9 *This ) 668bf215546Sopenharmony_ci{ 669bf215546Sopenharmony_ci return This->screen; 670bf215546Sopenharmony_ci} 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_cistruct pipe_context * 673bf215546Sopenharmony_ciNineDevice9_GetPipe( struct NineDevice9 *This ) 674bf215546Sopenharmony_ci{ 675bf215546Sopenharmony_ci return nine_context_get_pipe(This); 676bf215546Sopenharmony_ci} 677bf215546Sopenharmony_ci 678bf215546Sopenharmony_ciconst D3DCAPS9 * 679bf215546Sopenharmony_ciNineDevice9_GetCaps( struct NineDevice9 *This ) 680bf215546Sopenharmony_ci{ 681bf215546Sopenharmony_ci return &This->caps; 682bf215546Sopenharmony_ci} 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_cistatic inline void 685bf215546Sopenharmony_ciNineDevice9_PauseRecording( struct NineDevice9 *This ) 686bf215546Sopenharmony_ci{ 687bf215546Sopenharmony_ci if (This->record) { 688bf215546Sopenharmony_ci This->update = &This->state; 689bf215546Sopenharmony_ci This->is_recording = FALSE; 690bf215546Sopenharmony_ci } 691bf215546Sopenharmony_ci} 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_cistatic inline void 694bf215546Sopenharmony_ciNineDevice9_ResumeRecording( struct NineDevice9 *This ) 695bf215546Sopenharmony_ci{ 696bf215546Sopenharmony_ci if (This->record) { 697bf215546Sopenharmony_ci This->update = &This->record->state; 698bf215546Sopenharmony_ci This->is_recording = TRUE; 699bf215546Sopenharmony_ci } 700bf215546Sopenharmony_ci} 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ciHRESULT NINE_WINAPI 703bf215546Sopenharmony_ciNineDevice9_TestCooperativeLevel( struct NineDevice9 *This ) 704bf215546Sopenharmony_ci{ 705bf215546Sopenharmony_ci if (NineSwapChain9_GetOccluded(This->swapchains[0])) { 706bf215546Sopenharmony_ci This->device_needs_reset = TRUE; 707bf215546Sopenharmony_ci return D3DERR_DEVICELOST; 708bf215546Sopenharmony_ci } else if (NineSwapChain9_ResolutionMismatch(This->swapchains[0])) { 709bf215546Sopenharmony_ci This->device_needs_reset = TRUE; 710bf215546Sopenharmony_ci return D3DERR_DEVICENOTRESET; 711bf215546Sopenharmony_ci } else if (This->device_needs_reset) { 712bf215546Sopenharmony_ci return D3DERR_DEVICENOTRESET; 713bf215546Sopenharmony_ci } 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci return D3D_OK; 716bf215546Sopenharmony_ci} 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ciUINT NINE_WINAPI 719bf215546Sopenharmony_ciNineDevice9_GetAvailableTextureMem( struct NineDevice9 *This ) 720bf215546Sopenharmony_ci{ 721bf215546Sopenharmony_ci /* To prevent overflows - Not sure how this should be handled */ 722bf215546Sopenharmony_ci return (UINT)MIN2(This->available_texture_mem, (long long)(UINT_MAX - (64 << 20))); /* 64 MB margin */ 723bf215546Sopenharmony_ci} 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_civoid 726bf215546Sopenharmony_ciNineDevice9_EvictManagedResourcesInternal( struct NineDevice9 *This ) 727bf215546Sopenharmony_ci{ 728bf215546Sopenharmony_ci struct NineBaseTexture9 *tex; 729bf215546Sopenharmony_ci 730bf215546Sopenharmony_ci DBG("This=%p\n", This); 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_ci /* This function is called internally when an allocation fails. 733bf215546Sopenharmony_ci * We are supposed to release old unused managed textures/buffers, 734bf215546Sopenharmony_ci * until we have enough space for the allocation. 735bf215546Sopenharmony_ci * For now just release everything, except the bound textures, 736bf215546Sopenharmony_ci * as this function can be called when uploading bound textures. 737bf215546Sopenharmony_ci */ 738bf215546Sopenharmony_ci LIST_FOR_EACH_ENTRY(tex, &This->managed_textures, list2) { 739bf215546Sopenharmony_ci if (!tex->bind_count) 740bf215546Sopenharmony_ci NineBaseTexture9_UnLoad(tex); 741bf215546Sopenharmony_ci } 742bf215546Sopenharmony_ci} 743bf215546Sopenharmony_ci 744bf215546Sopenharmony_ciHRESULT NINE_WINAPI 745bf215546Sopenharmony_ciNineDevice9_EvictManagedResources( struct NineDevice9 *This ) 746bf215546Sopenharmony_ci{ 747bf215546Sopenharmony_ci struct NineBaseTexture9 *tex; 748bf215546Sopenharmony_ci struct NineBuffer9 *buf; 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_ci DBG("This=%p\n", This); 751bf215546Sopenharmony_ci LIST_FOR_EACH_ENTRY(tex, &This->managed_textures, list2) { 752bf215546Sopenharmony_ci NineBaseTexture9_UnLoad(tex); 753bf215546Sopenharmony_ci } 754bf215546Sopenharmony_ci /* Vertex/index buffers don't take a lot of space and aren't accounted 755bf215546Sopenharmony_ci * for d3d memory usage. Instead of actually freeing from memory, 756bf215546Sopenharmony_ci * just mark the buffer dirty to trigger a re-upload later. We 757bf215546Sopenharmony_ci * could just ignore, but some bad behaving apps could rely on it (if 758bf215546Sopenharmony_ci * they write outside the locked regions typically). */ 759bf215546Sopenharmony_ci LIST_FOR_EACH_ENTRY(buf, &This->managed_buffers, managed.list2) { 760bf215546Sopenharmony_ci NineBuffer9_SetDirty(buf); 761bf215546Sopenharmony_ci } 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci return D3D_OK; 764bf215546Sopenharmony_ci} 765bf215546Sopenharmony_ci 766bf215546Sopenharmony_ciHRESULT NINE_WINAPI 767bf215546Sopenharmony_ciNineDevice9_GetDirect3D( struct NineDevice9 *This, 768bf215546Sopenharmony_ci IDirect3D9 **ppD3D9 ) 769bf215546Sopenharmony_ci{ 770bf215546Sopenharmony_ci user_assert(ppD3D9 != NULL, E_POINTER); 771bf215546Sopenharmony_ci IDirect3D9_AddRef(This->d3d9); 772bf215546Sopenharmony_ci *ppD3D9 = This->d3d9; 773bf215546Sopenharmony_ci return D3D_OK; 774bf215546Sopenharmony_ci} 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ciHRESULT NINE_WINAPI 777bf215546Sopenharmony_ciNineDevice9_GetDeviceCaps( struct NineDevice9 *This, 778bf215546Sopenharmony_ci D3DCAPS9 *pCaps ) 779bf215546Sopenharmony_ci{ 780bf215546Sopenharmony_ci user_assert(pCaps != NULL, D3DERR_INVALIDCALL); 781bf215546Sopenharmony_ci *pCaps = This->caps; 782bf215546Sopenharmony_ci return D3D_OK; 783bf215546Sopenharmony_ci} 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ciHRESULT NINE_WINAPI 786bf215546Sopenharmony_ciNineDevice9_GetDisplayMode( struct NineDevice9 *This, 787bf215546Sopenharmony_ci UINT iSwapChain, 788bf215546Sopenharmony_ci D3DDISPLAYMODE *pMode ) 789bf215546Sopenharmony_ci{ 790bf215546Sopenharmony_ci DBG("This=%p iSwapChain=%u pMode=%p\n", This, iSwapChain, pMode); 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_ci user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 793bf215546Sopenharmony_ci 794bf215546Sopenharmony_ci return NineSwapChain9_GetDisplayMode(This->swapchains[iSwapChain], pMode); 795bf215546Sopenharmony_ci} 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ciHRESULT NINE_WINAPI 798bf215546Sopenharmony_ciNineDevice9_GetCreationParameters( struct NineDevice9 *This, 799bf215546Sopenharmony_ci D3DDEVICE_CREATION_PARAMETERS *pParameters ) 800bf215546Sopenharmony_ci{ 801bf215546Sopenharmony_ci user_assert(pParameters != NULL, D3DERR_INVALIDCALL); 802bf215546Sopenharmony_ci *pParameters = This->params; 803bf215546Sopenharmony_ci return D3D_OK; 804bf215546Sopenharmony_ci} 805bf215546Sopenharmony_ci 806bf215546Sopenharmony_ciHRESULT NINE_WINAPI 807bf215546Sopenharmony_ciNineDevice9_SetCursorProperties( struct NineDevice9 *This, 808bf215546Sopenharmony_ci UINT XHotSpot, 809bf215546Sopenharmony_ci UINT YHotSpot, 810bf215546Sopenharmony_ci IDirect3DSurface9 *pCursorBitmap ) 811bf215546Sopenharmony_ci{ 812bf215546Sopenharmony_ci struct NineSurface9 *surf = NineSurface9(pCursorBitmap); 813bf215546Sopenharmony_ci struct pipe_context *pipe = NineDevice9_GetPipe(This); 814bf215546Sopenharmony_ci struct pipe_box box; 815bf215546Sopenharmony_ci struct pipe_transfer *transfer; 816bf215546Sopenharmony_ci BOOL hw_cursor; 817bf215546Sopenharmony_ci void *ptr; 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci DBG_FLAG(DBG_SWAPCHAIN, "This=%p XHotSpot=%u YHotSpot=%u " 820bf215546Sopenharmony_ci "pCursorBitmap=%p\n", This, XHotSpot, YHotSpot, pCursorBitmap); 821bf215546Sopenharmony_ci 822bf215546Sopenharmony_ci user_assert(pCursorBitmap, D3DERR_INVALIDCALL); 823bf215546Sopenharmony_ci user_assert(surf->desc.Format == D3DFMT_A8R8G8B8, D3DERR_INVALIDCALL); 824bf215546Sopenharmony_ci 825bf215546Sopenharmony_ci if (This->swapchains[0]->params.Windowed) { 826bf215546Sopenharmony_ci This->cursor.w = MIN2(surf->desc.Width, 32); 827bf215546Sopenharmony_ci This->cursor.h = MIN2(surf->desc.Height, 32); 828bf215546Sopenharmony_ci hw_cursor = 1; /* always use hw cursor for windowed mode */ 829bf215546Sopenharmony_ci } else { 830bf215546Sopenharmony_ci This->cursor.w = MIN2(surf->desc.Width, This->cursor.image->width0); 831bf215546Sopenharmony_ci This->cursor.h = MIN2(surf->desc.Height, This->cursor.image->height0); 832bf215546Sopenharmony_ci hw_cursor = This->cursor.w == 32 && This->cursor.h == 32; 833bf215546Sopenharmony_ci } 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci u_box_origin_2d(This->cursor.w, This->cursor.h, &box); 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ci ptr = pipe->texture_map(pipe, This->cursor.image, 0, 838bf215546Sopenharmony_ci PIPE_MAP_WRITE | 839bf215546Sopenharmony_ci PIPE_MAP_DISCARD_WHOLE_RESOURCE, 840bf215546Sopenharmony_ci &box, &transfer); 841bf215546Sopenharmony_ci if (!ptr) 842bf215546Sopenharmony_ci ret_err("Failed to update cursor image.\n", D3DERR_DRIVERINTERNALERROR); 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_ci This->cursor.hotspot.x = XHotSpot; 845bf215546Sopenharmony_ci This->cursor.hotspot.y = YHotSpot; 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci /* Copy cursor image to internal storage. */ 848bf215546Sopenharmony_ci { 849bf215546Sopenharmony_ci D3DLOCKED_RECT lock; 850bf215546Sopenharmony_ci HRESULT hr; 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci hr = NineSurface9_LockRect(surf, &lock, NULL, D3DLOCK_READONLY); 853bf215546Sopenharmony_ci if (FAILED(hr)) 854bf215546Sopenharmony_ci ret_err("Failed to map cursor source image.\n", 855bf215546Sopenharmony_ci D3DERR_DRIVERINTERNALERROR); 856bf215546Sopenharmony_ci 857bf215546Sopenharmony_ci util_format_unpack_rgba_8unorm_rect(surf->base.info.format, ptr, transfer->stride, 858bf215546Sopenharmony_ci lock.pBits, lock.Pitch, 859bf215546Sopenharmony_ci This->cursor.w, This->cursor.h); 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci if (hw_cursor) { 862bf215546Sopenharmony_ci void *data = lock.pBits; 863bf215546Sopenharmony_ci /* SetCursor assumes 32x32 argb with pitch 128 */ 864bf215546Sopenharmony_ci if (lock.Pitch != 128) { 865bf215546Sopenharmony_ci util_format_unpack_rgba_8unorm_rect(surf->base.info.format, 866bf215546Sopenharmony_ci This->cursor.hw_upload_temp, 128, 867bf215546Sopenharmony_ci lock.pBits, lock.Pitch, 868bf215546Sopenharmony_ci 32, 32); 869bf215546Sopenharmony_ci data = This->cursor.hw_upload_temp; 870bf215546Sopenharmony_ci } 871bf215546Sopenharmony_ci hw_cursor = ID3DPresent_SetCursor(This->swapchains[0]->present, 872bf215546Sopenharmony_ci data, 873bf215546Sopenharmony_ci &This->cursor.hotspot, 874bf215546Sopenharmony_ci This->cursor.visible) == D3D_OK; 875bf215546Sopenharmony_ci } 876bf215546Sopenharmony_ci 877bf215546Sopenharmony_ci NineSurface9_UnlockRect(surf); 878bf215546Sopenharmony_ci } 879bf215546Sopenharmony_ci pipe->texture_unmap(pipe, transfer); 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_ci /* hide cursor if we emulate it */ 882bf215546Sopenharmony_ci if (!hw_cursor) 883bf215546Sopenharmony_ci ID3DPresent_SetCursor(This->swapchains[0]->present, NULL, NULL, FALSE); 884bf215546Sopenharmony_ci This->cursor.software = !hw_cursor; 885bf215546Sopenharmony_ci 886bf215546Sopenharmony_ci return D3D_OK; 887bf215546Sopenharmony_ci} 888bf215546Sopenharmony_ci 889bf215546Sopenharmony_civoid NINE_WINAPI 890bf215546Sopenharmony_ciNineDevice9_SetCursorPosition( struct NineDevice9 *This, 891bf215546Sopenharmony_ci int X, 892bf215546Sopenharmony_ci int Y, 893bf215546Sopenharmony_ci DWORD Flags ) 894bf215546Sopenharmony_ci{ 895bf215546Sopenharmony_ci struct NineSwapChain9 *swap = This->swapchains[0]; 896bf215546Sopenharmony_ci 897bf215546Sopenharmony_ci DBG("This=%p X=%d Y=%d Flags=%d\n", This, X, Y, Flags); 898bf215546Sopenharmony_ci 899bf215546Sopenharmony_ci /* present >= v1.4 handles this itself */ 900bf215546Sopenharmony_ci if (This->minor_version_num < 4) { 901bf215546Sopenharmony_ci if (This->cursor.pos.x == X && This->cursor.pos.y == Y) 902bf215546Sopenharmony_ci return; 903bf215546Sopenharmony_ci } 904bf215546Sopenharmony_ci 905bf215546Sopenharmony_ci This->cursor.pos.x = X; 906bf215546Sopenharmony_ci This->cursor.pos.y = Y; 907bf215546Sopenharmony_ci 908bf215546Sopenharmony_ci if (!This->cursor.software) 909bf215546Sopenharmony_ci This->cursor.software = ID3DPresent_SetCursorPos(swap->present, &This->cursor.pos) != D3D_OK; 910bf215546Sopenharmony_ci} 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ciBOOL NINE_WINAPI 913bf215546Sopenharmony_ciNineDevice9_ShowCursor( struct NineDevice9 *This, 914bf215546Sopenharmony_ci BOOL bShow ) 915bf215546Sopenharmony_ci{ 916bf215546Sopenharmony_ci BOOL old = This->cursor.visible; 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci DBG("This=%p bShow=%d\n", This, (int) bShow); 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_ci /* No-op until a cursor is set in d3d */ 921bf215546Sopenharmony_ci if (This->cursor.hotspot.x == -1) 922bf215546Sopenharmony_ci return old; 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci This->cursor.visible = bShow; 925bf215546Sopenharmony_ci /* Note: Don't optimize by avoiding the call if This->cursor.visible 926bf215546Sopenharmony_ci * hasn't changed. One has to keep in mind the app may do SetCursor 927bf215546Sopenharmony_ci * calls outside d3d, thus such an optimization affects behaviour. */ 928bf215546Sopenharmony_ci if (!This->cursor.software) 929bf215546Sopenharmony_ci This->cursor.software = ID3DPresent_SetCursor(This->swapchains[0]->present, NULL, NULL, bShow) != D3D_OK; 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci return old; 932bf215546Sopenharmony_ci} 933bf215546Sopenharmony_ci 934bf215546Sopenharmony_ciHRESULT NINE_WINAPI 935bf215546Sopenharmony_ciNineDevice9_CreateAdditionalSwapChain( struct NineDevice9 *This, 936bf215546Sopenharmony_ci D3DPRESENT_PARAMETERS *pPresentationParameters, 937bf215546Sopenharmony_ci IDirect3DSwapChain9 **pSwapChain ) 938bf215546Sopenharmony_ci{ 939bf215546Sopenharmony_ci struct NineSwapChain9 *swapchain, *tmplt = This->swapchains[0]; 940bf215546Sopenharmony_ci ID3DPresent *present; 941bf215546Sopenharmony_ci HRESULT hr; 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci DBG("This=%p pPresentationParameters=%p pSwapChain=%p\n", 944bf215546Sopenharmony_ci This, pPresentationParameters, pSwapChain); 945bf215546Sopenharmony_ci 946bf215546Sopenharmony_ci user_assert(pPresentationParameters, D3DERR_INVALIDCALL); 947bf215546Sopenharmony_ci user_assert(pSwapChain != NULL, D3DERR_INVALIDCALL); 948bf215546Sopenharmony_ci user_assert(tmplt->params.Windowed && pPresentationParameters->Windowed, D3DERR_INVALIDCALL); 949bf215546Sopenharmony_ci 950bf215546Sopenharmony_ci /* TODO: this deserves more tests */ 951bf215546Sopenharmony_ci if (!pPresentationParameters->hDeviceWindow) 952bf215546Sopenharmony_ci pPresentationParameters->hDeviceWindow = This->params.hFocusWindow; 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_ci hr = ID3DPresentGroup_CreateAdditionalPresent(This->present, pPresentationParameters, &present); 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci if (FAILED(hr)) 957bf215546Sopenharmony_ci return hr; 958bf215546Sopenharmony_ci 959bf215546Sopenharmony_ci hr = NineSwapChain9_new(This, FALSE, present, pPresentationParameters, 960bf215546Sopenharmony_ci tmplt->actx, 961bf215546Sopenharmony_ci tmplt->params.hDeviceWindow, 962bf215546Sopenharmony_ci &swapchain); 963bf215546Sopenharmony_ci if (FAILED(hr)) 964bf215546Sopenharmony_ci return hr; 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci *pSwapChain = (IDirect3DSwapChain9 *)swapchain; 967bf215546Sopenharmony_ci return D3D_OK; 968bf215546Sopenharmony_ci} 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ciHRESULT NINE_WINAPI 971bf215546Sopenharmony_ciNineDevice9_GetSwapChain( struct NineDevice9 *This, 972bf215546Sopenharmony_ci UINT iSwapChain, 973bf215546Sopenharmony_ci IDirect3DSwapChain9 **pSwapChain ) 974bf215546Sopenharmony_ci{ 975bf215546Sopenharmony_ci user_assert(pSwapChain != NULL, D3DERR_INVALIDCALL); 976bf215546Sopenharmony_ci 977bf215546Sopenharmony_ci *pSwapChain = NULL; 978bf215546Sopenharmony_ci user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 979bf215546Sopenharmony_ci 980bf215546Sopenharmony_ci NineUnknown_AddRef(NineUnknown(This->swapchains[iSwapChain])); 981bf215546Sopenharmony_ci *pSwapChain = (IDirect3DSwapChain9 *)This->swapchains[iSwapChain]; 982bf215546Sopenharmony_ci 983bf215546Sopenharmony_ci return D3D_OK; 984bf215546Sopenharmony_ci} 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_ciUINT NINE_WINAPI 987bf215546Sopenharmony_ciNineDevice9_GetNumberOfSwapChains( struct NineDevice9 *This ) 988bf215546Sopenharmony_ci{ 989bf215546Sopenharmony_ci return This->nswapchains; 990bf215546Sopenharmony_ci} 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_ciHRESULT NINE_WINAPI 993bf215546Sopenharmony_ciNineDevice9_Reset( struct NineDevice9 *This, 994bf215546Sopenharmony_ci D3DPRESENT_PARAMETERS *pPresentationParameters ) 995bf215546Sopenharmony_ci{ 996bf215546Sopenharmony_ci HRESULT hr = D3D_OK; 997bf215546Sopenharmony_ci unsigned i; 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_ci DBG("This=%p pPresentationParameters=%p\n", This, pPresentationParameters); 1000bf215546Sopenharmony_ci 1001bf215546Sopenharmony_ci user_assert(pPresentationParameters != NULL, D3DERR_INVALIDCALL); 1002bf215546Sopenharmony_ci 1003bf215546Sopenharmony_ci if (NineSwapChain9_GetOccluded(This->swapchains[0])) { 1004bf215546Sopenharmony_ci This->device_needs_reset = TRUE; 1005bf215546Sopenharmony_ci return D3DERR_DEVICELOST; 1006bf215546Sopenharmony_ci } 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci for (i = 0; i < This->nswapchains; ++i) { 1009bf215546Sopenharmony_ci D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i]; 1010bf215546Sopenharmony_ci hr = NineSwapChain9_Resize(This->swapchains[i], params, NULL); 1011bf215546Sopenharmony_ci if (hr != D3D_OK) 1012bf215546Sopenharmony_ci break; 1013bf215546Sopenharmony_ci } 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci nine_csmt_process(This); 1016bf215546Sopenharmony_ci nine_device_state_clear(This); 1017bf215546Sopenharmony_ci nine_context_clear(This); 1018bf215546Sopenharmony_ci 1019bf215546Sopenharmony_ci NineDevice9_SetDefaultState(This, TRUE); 1020bf215546Sopenharmony_ci NineDevice9_SetRenderTarget( 1021bf215546Sopenharmony_ci This, 0, (IDirect3DSurface9 *)This->swapchains[0]->buffers[0]); 1022bf215546Sopenharmony_ci /* XXX: better use GetBackBuffer here ? */ 1023bf215546Sopenharmony_ci 1024bf215546Sopenharmony_ci This->device_needs_reset = (hr != D3D_OK); 1025bf215546Sopenharmony_ci return hr; 1026bf215546Sopenharmony_ci} 1027bf215546Sopenharmony_ci 1028bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1029bf215546Sopenharmony_ciNineDevice9_Present( struct NineDevice9 *This, 1030bf215546Sopenharmony_ci const RECT *pSourceRect, 1031bf215546Sopenharmony_ci const RECT *pDestRect, 1032bf215546Sopenharmony_ci HWND hDestWindowOverride, 1033bf215546Sopenharmony_ci const RGNDATA *pDirtyRegion ) 1034bf215546Sopenharmony_ci{ 1035bf215546Sopenharmony_ci unsigned i; 1036bf215546Sopenharmony_ci HRESULT hr; 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_ci DBG("This=%p pSourceRect=%p pDestRect=%p hDestWindowOverride=%p pDirtyRegion=%p\n", 1039bf215546Sopenharmony_ci This, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); 1040bf215546Sopenharmony_ci 1041bf215546Sopenharmony_ci /* XXX is this right? */ 1042bf215546Sopenharmony_ci for (i = 0; i < This->nswapchains; ++i) { 1043bf215546Sopenharmony_ci hr = NineSwapChain9_Present(This->swapchains[i], pSourceRect, pDestRect, 1044bf215546Sopenharmony_ci hDestWindowOverride, pDirtyRegion, 0); 1045bf215546Sopenharmony_ci if (FAILED(hr)) { return hr; } 1046bf215546Sopenharmony_ci } 1047bf215546Sopenharmony_ci 1048bf215546Sopenharmony_ci return D3D_OK; 1049bf215546Sopenharmony_ci} 1050bf215546Sopenharmony_ci 1051bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1052bf215546Sopenharmony_ciNineDevice9_GetBackBuffer( struct NineDevice9 *This, 1053bf215546Sopenharmony_ci UINT iSwapChain, 1054bf215546Sopenharmony_ci UINT iBackBuffer, 1055bf215546Sopenharmony_ci D3DBACKBUFFER_TYPE Type, 1056bf215546Sopenharmony_ci IDirect3DSurface9 **ppBackBuffer ) 1057bf215546Sopenharmony_ci{ 1058bf215546Sopenharmony_ci user_assert(ppBackBuffer != NULL, D3DERR_INVALIDCALL); 1059bf215546Sopenharmony_ci /* return NULL on error */ 1060bf215546Sopenharmony_ci *ppBackBuffer = NULL; 1061bf215546Sopenharmony_ci user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci return NineSwapChain9_GetBackBuffer(This->swapchains[iSwapChain], 1064bf215546Sopenharmony_ci iBackBuffer, Type, ppBackBuffer); 1065bf215546Sopenharmony_ci} 1066bf215546Sopenharmony_ci 1067bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1068bf215546Sopenharmony_ciNineDevice9_GetRasterStatus( struct NineDevice9 *This, 1069bf215546Sopenharmony_ci UINT iSwapChain, 1070bf215546Sopenharmony_ci D3DRASTER_STATUS *pRasterStatus ) 1071bf215546Sopenharmony_ci{ 1072bf215546Sopenharmony_ci user_assert(pRasterStatus != NULL, D3DERR_INVALIDCALL); 1073bf215546Sopenharmony_ci user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 1074bf215546Sopenharmony_ci 1075bf215546Sopenharmony_ci return NineSwapChain9_GetRasterStatus(This->swapchains[iSwapChain], 1076bf215546Sopenharmony_ci pRasterStatus); 1077bf215546Sopenharmony_ci} 1078bf215546Sopenharmony_ci 1079bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1080bf215546Sopenharmony_ciNineDevice9_SetDialogBoxMode( struct NineDevice9 *This, 1081bf215546Sopenharmony_ci BOOL bEnableDialogs ) 1082bf215546Sopenharmony_ci{ 1083bf215546Sopenharmony_ci STUB(D3DERR_INVALIDCALL); 1084bf215546Sopenharmony_ci} 1085bf215546Sopenharmony_ci 1086bf215546Sopenharmony_civoid NINE_WINAPI 1087bf215546Sopenharmony_ciNineDevice9_SetGammaRamp( struct NineDevice9 *This, 1088bf215546Sopenharmony_ci UINT iSwapChain, 1089bf215546Sopenharmony_ci DWORD Flags, 1090bf215546Sopenharmony_ci const D3DGAMMARAMP *pRamp ) 1091bf215546Sopenharmony_ci{ 1092bf215546Sopenharmony_ci DBG("This=%p iSwapChain=%u Flags=%x pRamp=%p\n", This, 1093bf215546Sopenharmony_ci iSwapChain, Flags, pRamp); 1094bf215546Sopenharmony_ci 1095bf215546Sopenharmony_ci user_warn(iSwapChain >= This->nswapchains); 1096bf215546Sopenharmony_ci user_warn(!pRamp); 1097bf215546Sopenharmony_ci 1098bf215546Sopenharmony_ci if (pRamp && (iSwapChain < This->nswapchains)) { 1099bf215546Sopenharmony_ci struct NineSwapChain9 *swap = This->swapchains[iSwapChain]; 1100bf215546Sopenharmony_ci swap->gamma = *pRamp; 1101bf215546Sopenharmony_ci ID3DPresent_SetGammaRamp(swap->present, pRamp, swap->params.hDeviceWindow); 1102bf215546Sopenharmony_ci } 1103bf215546Sopenharmony_ci} 1104bf215546Sopenharmony_ci 1105bf215546Sopenharmony_civoid NINE_WINAPI 1106bf215546Sopenharmony_ciNineDevice9_GetGammaRamp( struct NineDevice9 *This, 1107bf215546Sopenharmony_ci UINT iSwapChain, 1108bf215546Sopenharmony_ci D3DGAMMARAMP *pRamp ) 1109bf215546Sopenharmony_ci{ 1110bf215546Sopenharmony_ci DBG("This=%p iSwapChain=%u pRamp=%p\n", This, iSwapChain, pRamp); 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_ci user_warn(iSwapChain >= This->nswapchains); 1113bf215546Sopenharmony_ci user_warn(!pRamp); 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_ci if (pRamp && (iSwapChain < This->nswapchains)) 1116bf215546Sopenharmony_ci *pRamp = This->swapchains[iSwapChain]->gamma; 1117bf215546Sopenharmony_ci} 1118bf215546Sopenharmony_ci 1119bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1120bf215546Sopenharmony_ciNineDevice9_CreateTexture( struct NineDevice9 *This, 1121bf215546Sopenharmony_ci UINT Width, 1122bf215546Sopenharmony_ci UINT Height, 1123bf215546Sopenharmony_ci UINT Levels, 1124bf215546Sopenharmony_ci DWORD Usage, 1125bf215546Sopenharmony_ci D3DFORMAT Format, 1126bf215546Sopenharmony_ci D3DPOOL Pool, 1127bf215546Sopenharmony_ci IDirect3DTexture9 **ppTexture, 1128bf215546Sopenharmony_ci HANDLE *pSharedHandle ) 1129bf215546Sopenharmony_ci{ 1130bf215546Sopenharmony_ci struct NineTexture9 *tex; 1131bf215546Sopenharmony_ci HRESULT hr; 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_ci DBG("This=%p Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s " 1134bf215546Sopenharmony_ci "ppOut=%p pSharedHandle=%p\n", This, Width, Height, Levels, 1135bf215546Sopenharmony_ci nine_D3DUSAGE_to_str(Usage), d3dformat_to_string(Format), 1136bf215546Sopenharmony_ci nine_D3DPOOL_to_str(Pool), ppTexture, pSharedHandle); 1137bf215546Sopenharmony_ci 1138bf215546Sopenharmony_ci user_assert(ppTexture != NULL, D3DERR_INVALIDCALL); 1139bf215546Sopenharmony_ci 1140bf215546Sopenharmony_ci Usage &= D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_DMAP | 1141bf215546Sopenharmony_ci D3DUSAGE_DYNAMIC | D3DUSAGE_NONSECURE | D3DUSAGE_RENDERTARGET | 1142bf215546Sopenharmony_ci D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_TEXTAPI; 1143bf215546Sopenharmony_ci 1144bf215546Sopenharmony_ci *ppTexture = NULL; 1145bf215546Sopenharmony_ci 1146bf215546Sopenharmony_ci hr = NineTexture9_new(This, Width, Height, Levels, Usage, Format, Pool, 1147bf215546Sopenharmony_ci &tex, pSharedHandle); 1148bf215546Sopenharmony_ci if (SUCCEEDED(hr)) 1149bf215546Sopenharmony_ci *ppTexture = (IDirect3DTexture9 *)tex; 1150bf215546Sopenharmony_ci 1151bf215546Sopenharmony_ci return hr; 1152bf215546Sopenharmony_ci} 1153bf215546Sopenharmony_ci 1154bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1155bf215546Sopenharmony_ciNineDevice9_CreateVolumeTexture( struct NineDevice9 *This, 1156bf215546Sopenharmony_ci UINT Width, 1157bf215546Sopenharmony_ci UINT Height, 1158bf215546Sopenharmony_ci UINT Depth, 1159bf215546Sopenharmony_ci UINT Levels, 1160bf215546Sopenharmony_ci DWORD Usage, 1161bf215546Sopenharmony_ci D3DFORMAT Format, 1162bf215546Sopenharmony_ci D3DPOOL Pool, 1163bf215546Sopenharmony_ci IDirect3DVolumeTexture9 **ppVolumeTexture, 1164bf215546Sopenharmony_ci HANDLE *pSharedHandle ) 1165bf215546Sopenharmony_ci{ 1166bf215546Sopenharmony_ci struct NineVolumeTexture9 *tex; 1167bf215546Sopenharmony_ci HRESULT hr; 1168bf215546Sopenharmony_ci 1169bf215546Sopenharmony_ci DBG("This=%p Width=%u Height=%u Depth=%u Levels=%u Usage=%s Format=%s Pool=%s " 1170bf215546Sopenharmony_ci "ppOut=%p pSharedHandle=%p\n", This, Width, Height, Depth, Levels, 1171bf215546Sopenharmony_ci nine_D3DUSAGE_to_str(Usage), d3dformat_to_string(Format), 1172bf215546Sopenharmony_ci nine_D3DPOOL_to_str(Pool), ppVolumeTexture, pSharedHandle); 1173bf215546Sopenharmony_ci 1174bf215546Sopenharmony_ci user_assert(ppVolumeTexture != NULL, D3DERR_INVALIDCALL); 1175bf215546Sopenharmony_ci 1176bf215546Sopenharmony_ci Usage &= D3DUSAGE_DYNAMIC | D3DUSAGE_NONSECURE | 1177bf215546Sopenharmony_ci D3DUSAGE_SOFTWAREPROCESSING; 1178bf215546Sopenharmony_ci 1179bf215546Sopenharmony_ci *ppVolumeTexture = NULL; 1180bf215546Sopenharmony_ci 1181bf215546Sopenharmony_ci hr = NineVolumeTexture9_new(This, Width, Height, Depth, Levels, 1182bf215546Sopenharmony_ci Usage, Format, Pool, &tex, pSharedHandle); 1183bf215546Sopenharmony_ci if (SUCCEEDED(hr)) 1184bf215546Sopenharmony_ci *ppVolumeTexture = (IDirect3DVolumeTexture9 *)tex; 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci return hr; 1187bf215546Sopenharmony_ci} 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1190bf215546Sopenharmony_ciNineDevice9_CreateCubeTexture( struct NineDevice9 *This, 1191bf215546Sopenharmony_ci UINT EdgeLength, 1192bf215546Sopenharmony_ci UINT Levels, 1193bf215546Sopenharmony_ci DWORD Usage, 1194bf215546Sopenharmony_ci D3DFORMAT Format, 1195bf215546Sopenharmony_ci D3DPOOL Pool, 1196bf215546Sopenharmony_ci IDirect3DCubeTexture9 **ppCubeTexture, 1197bf215546Sopenharmony_ci HANDLE *pSharedHandle ) 1198bf215546Sopenharmony_ci{ 1199bf215546Sopenharmony_ci struct NineCubeTexture9 *tex; 1200bf215546Sopenharmony_ci HRESULT hr; 1201bf215546Sopenharmony_ci 1202bf215546Sopenharmony_ci DBG("This=%p EdgeLength=%u Levels=%u Usage=%s Format=%s Pool=%s ppOut=%p " 1203bf215546Sopenharmony_ci "pSharedHandle=%p\n", This, EdgeLength, Levels, 1204bf215546Sopenharmony_ci nine_D3DUSAGE_to_str(Usage), d3dformat_to_string(Format), 1205bf215546Sopenharmony_ci nine_D3DPOOL_to_str(Pool), ppCubeTexture, pSharedHandle); 1206bf215546Sopenharmony_ci 1207bf215546Sopenharmony_ci user_assert(ppCubeTexture != NULL, D3DERR_INVALIDCALL); 1208bf215546Sopenharmony_ci 1209bf215546Sopenharmony_ci Usage &= D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_DYNAMIC | 1210bf215546Sopenharmony_ci D3DUSAGE_NONSECURE | D3DUSAGE_RENDERTARGET | 1211bf215546Sopenharmony_ci D3DUSAGE_SOFTWAREPROCESSING; 1212bf215546Sopenharmony_ci 1213bf215546Sopenharmony_ci *ppCubeTexture = NULL; 1214bf215546Sopenharmony_ci 1215bf215546Sopenharmony_ci hr = NineCubeTexture9_new(This, EdgeLength, Levels, Usage, Format, Pool, 1216bf215546Sopenharmony_ci &tex, pSharedHandle); 1217bf215546Sopenharmony_ci if (SUCCEEDED(hr)) 1218bf215546Sopenharmony_ci *ppCubeTexture = (IDirect3DCubeTexture9 *)tex; 1219bf215546Sopenharmony_ci 1220bf215546Sopenharmony_ci return hr; 1221bf215546Sopenharmony_ci} 1222bf215546Sopenharmony_ci 1223bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1224bf215546Sopenharmony_ciNineDevice9_CreateVertexBuffer( struct NineDevice9 *This, 1225bf215546Sopenharmony_ci UINT Length, 1226bf215546Sopenharmony_ci DWORD Usage, 1227bf215546Sopenharmony_ci DWORD FVF, 1228bf215546Sopenharmony_ci D3DPOOL Pool, 1229bf215546Sopenharmony_ci IDirect3DVertexBuffer9 **ppVertexBuffer, 1230bf215546Sopenharmony_ci HANDLE *pSharedHandle ) 1231bf215546Sopenharmony_ci{ 1232bf215546Sopenharmony_ci struct NineVertexBuffer9 *buf; 1233bf215546Sopenharmony_ci HRESULT hr; 1234bf215546Sopenharmony_ci D3DVERTEXBUFFER_DESC desc; 1235bf215546Sopenharmony_ci 1236bf215546Sopenharmony_ci DBG("This=%p Length=%u Usage=%x FVF=%x Pool=%u ppOut=%p pSharedHandle=%p\n", 1237bf215546Sopenharmony_ci This, Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle); 1238bf215546Sopenharmony_ci 1239bf215546Sopenharmony_ci user_assert(ppVertexBuffer != NULL, D3DERR_INVALIDCALL); 1240bf215546Sopenharmony_ci user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_NOTAVAILABLE); 1241bf215546Sopenharmony_ci 1242bf215546Sopenharmony_ci desc.Format = D3DFMT_VERTEXDATA; 1243bf215546Sopenharmony_ci desc.Type = D3DRTYPE_VERTEXBUFFER; 1244bf215546Sopenharmony_ci desc.Usage = Usage & 1245bf215546Sopenharmony_ci (D3DUSAGE_DONOTCLIP | D3DUSAGE_DYNAMIC | D3DUSAGE_NONSECURE | 1246bf215546Sopenharmony_ci D3DUSAGE_NPATCHES | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | 1247bf215546Sopenharmony_ci D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_TEXTAPI | 1248bf215546Sopenharmony_ci D3DUSAGE_WRITEONLY); 1249bf215546Sopenharmony_ci desc.Pool = Pool; 1250bf215546Sopenharmony_ci desc.Size = Length; 1251bf215546Sopenharmony_ci desc.FVF = FVF; 1252bf215546Sopenharmony_ci 1253bf215546Sopenharmony_ci user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1254bf215546Sopenharmony_ci user_assert(desc.Usage == Usage, D3DERR_INVALIDCALL); 1255bf215546Sopenharmony_ci 1256bf215546Sopenharmony_ci hr = NineVertexBuffer9_new(This, &desc, &buf); 1257bf215546Sopenharmony_ci if (SUCCEEDED(hr)) 1258bf215546Sopenharmony_ci *ppVertexBuffer = (IDirect3DVertexBuffer9 *)buf; 1259bf215546Sopenharmony_ci return hr; 1260bf215546Sopenharmony_ci} 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1263bf215546Sopenharmony_ciNineDevice9_CreateIndexBuffer( struct NineDevice9 *This, 1264bf215546Sopenharmony_ci UINT Length, 1265bf215546Sopenharmony_ci DWORD Usage, 1266bf215546Sopenharmony_ci D3DFORMAT Format, 1267bf215546Sopenharmony_ci D3DPOOL Pool, 1268bf215546Sopenharmony_ci IDirect3DIndexBuffer9 **ppIndexBuffer, 1269bf215546Sopenharmony_ci HANDLE *pSharedHandle ) 1270bf215546Sopenharmony_ci{ 1271bf215546Sopenharmony_ci struct NineIndexBuffer9 *buf; 1272bf215546Sopenharmony_ci HRESULT hr; 1273bf215546Sopenharmony_ci D3DINDEXBUFFER_DESC desc; 1274bf215546Sopenharmony_ci 1275bf215546Sopenharmony_ci DBG("This=%p Length=%u Usage=%x Format=%s Pool=%u ppOut=%p " 1276bf215546Sopenharmony_ci "pSharedHandle=%p\n", This, Length, Usage, 1277bf215546Sopenharmony_ci d3dformat_to_string(Format), Pool, ppIndexBuffer, pSharedHandle); 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_ci user_assert(ppIndexBuffer != NULL, D3DERR_INVALIDCALL); 1280bf215546Sopenharmony_ci user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_NOTAVAILABLE); 1281bf215546Sopenharmony_ci 1282bf215546Sopenharmony_ci desc.Format = Format; 1283bf215546Sopenharmony_ci desc.Type = D3DRTYPE_INDEXBUFFER; 1284bf215546Sopenharmony_ci desc.Usage = Usage & 1285bf215546Sopenharmony_ci (D3DUSAGE_DONOTCLIP | D3DUSAGE_DYNAMIC | D3DUSAGE_NONSECURE | 1286bf215546Sopenharmony_ci D3DUSAGE_NPATCHES | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | 1287bf215546Sopenharmony_ci D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY); 1288bf215546Sopenharmony_ci desc.Pool = Pool; 1289bf215546Sopenharmony_ci desc.Size = Length; 1290bf215546Sopenharmony_ci 1291bf215546Sopenharmony_ci user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1292bf215546Sopenharmony_ci user_assert(desc.Usage == Usage, D3DERR_INVALIDCALL); 1293bf215546Sopenharmony_ci 1294bf215546Sopenharmony_ci hr = NineIndexBuffer9_new(This, &desc, &buf); 1295bf215546Sopenharmony_ci if (SUCCEEDED(hr)) 1296bf215546Sopenharmony_ci *ppIndexBuffer = (IDirect3DIndexBuffer9 *)buf; 1297bf215546Sopenharmony_ci return hr; 1298bf215546Sopenharmony_ci} 1299bf215546Sopenharmony_ci 1300bf215546Sopenharmony_cistatic HRESULT 1301bf215546Sopenharmony_cicreate_zs_or_rt_surface(struct NineDevice9 *This, 1302bf215546Sopenharmony_ci unsigned type, /* 0 = RT, 1 = ZS, 2 = plain */ 1303bf215546Sopenharmony_ci D3DPOOL Pool, 1304bf215546Sopenharmony_ci UINT Width, UINT Height, 1305bf215546Sopenharmony_ci D3DFORMAT Format, 1306bf215546Sopenharmony_ci D3DMULTISAMPLE_TYPE MultiSample, 1307bf215546Sopenharmony_ci DWORD MultisampleQuality, 1308bf215546Sopenharmony_ci BOOL Discard_or_Lockable, 1309bf215546Sopenharmony_ci IDirect3DSurface9 **ppSurface, 1310bf215546Sopenharmony_ci HANDLE *pSharedHandle) 1311bf215546Sopenharmony_ci{ 1312bf215546Sopenharmony_ci struct NineSurface9 *surface; 1313bf215546Sopenharmony_ci HRESULT hr; 1314bf215546Sopenharmony_ci D3DSURFACE_DESC desc; 1315bf215546Sopenharmony_ci 1316bf215546Sopenharmony_ci DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u " 1317bf215546Sopenharmony_ci "Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n", 1318bf215546Sopenharmony_ci This, type, nine_D3DPOOL_to_str(Pool), Width, Height, 1319bf215546Sopenharmony_ci d3dformat_to_string(Format), MultiSample, MultisampleQuality, 1320bf215546Sopenharmony_ci Discard_or_Lockable, ppSurface, pSharedHandle); 1321bf215546Sopenharmony_ci 1322bf215546Sopenharmony_ci if (pSharedHandle) 1323bf215546Sopenharmony_ci DBG("FIXME Used shared handle! This option isn't probably handled correctly!\n"); 1324bf215546Sopenharmony_ci 1325bf215546Sopenharmony_ci user_assert(Width && Height, D3DERR_INVALIDCALL); 1326bf215546Sopenharmony_ci user_assert(Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL); 1327bf215546Sopenharmony_ci 1328bf215546Sopenharmony_ci desc.Format = Format; 1329bf215546Sopenharmony_ci desc.Type = D3DRTYPE_SURFACE; 1330bf215546Sopenharmony_ci desc.Usage = 0; 1331bf215546Sopenharmony_ci desc.Pool = Pool; 1332bf215546Sopenharmony_ci desc.MultiSampleType = MultiSample; 1333bf215546Sopenharmony_ci desc.MultiSampleQuality = MultisampleQuality; 1334bf215546Sopenharmony_ci desc.Width = Width; 1335bf215546Sopenharmony_ci desc.Height = Height; 1336bf215546Sopenharmony_ci switch (type) { 1337bf215546Sopenharmony_ci case 0: desc.Usage = D3DUSAGE_RENDERTARGET; break; 1338bf215546Sopenharmony_ci case 1: desc.Usage = D3DUSAGE_DEPTHSTENCIL; break; 1339bf215546Sopenharmony_ci default: assert(type == 2); break; 1340bf215546Sopenharmony_ci } 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci hr = NineSurface9_new(This, NULL, NULL, NULL, 0, 0, 0, &desc, &surface); 1343bf215546Sopenharmony_ci if (SUCCEEDED(hr)) { 1344bf215546Sopenharmony_ci *ppSurface = (IDirect3DSurface9 *)surface; 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_ci if (surface->base.resource && Discard_or_Lockable && (type != 1)) 1347bf215546Sopenharmony_ci surface->base.resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; 1348bf215546Sopenharmony_ci } 1349bf215546Sopenharmony_ci 1350bf215546Sopenharmony_ci return hr; 1351bf215546Sopenharmony_ci} 1352bf215546Sopenharmony_ci 1353bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1354bf215546Sopenharmony_ciNineDevice9_CreateRenderTarget( struct NineDevice9 *This, 1355bf215546Sopenharmony_ci UINT Width, 1356bf215546Sopenharmony_ci UINT Height, 1357bf215546Sopenharmony_ci D3DFORMAT Format, 1358bf215546Sopenharmony_ci D3DMULTISAMPLE_TYPE MultiSample, 1359bf215546Sopenharmony_ci DWORD MultisampleQuality, 1360bf215546Sopenharmony_ci BOOL Lockable, 1361bf215546Sopenharmony_ci IDirect3DSurface9 **ppSurface, 1362bf215546Sopenharmony_ci HANDLE *pSharedHandle ) 1363bf215546Sopenharmony_ci{ 1364bf215546Sopenharmony_ci user_assert(ppSurface != NULL, D3DERR_INVALIDCALL); 1365bf215546Sopenharmony_ci *ppSurface = NULL; 1366bf215546Sopenharmony_ci return create_zs_or_rt_surface(This, 0, D3DPOOL_DEFAULT, 1367bf215546Sopenharmony_ci Width, Height, Format, 1368bf215546Sopenharmony_ci MultiSample, MultisampleQuality, 1369bf215546Sopenharmony_ci Lockable, ppSurface, pSharedHandle); 1370bf215546Sopenharmony_ci} 1371bf215546Sopenharmony_ci 1372bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1373bf215546Sopenharmony_ciNineDevice9_CreateDepthStencilSurface( struct NineDevice9 *This, 1374bf215546Sopenharmony_ci UINT Width, 1375bf215546Sopenharmony_ci UINT Height, 1376bf215546Sopenharmony_ci D3DFORMAT Format, 1377bf215546Sopenharmony_ci D3DMULTISAMPLE_TYPE MultiSample, 1378bf215546Sopenharmony_ci DWORD MultisampleQuality, 1379bf215546Sopenharmony_ci BOOL Discard, 1380bf215546Sopenharmony_ci IDirect3DSurface9 **ppSurface, 1381bf215546Sopenharmony_ci HANDLE *pSharedHandle ) 1382bf215546Sopenharmony_ci{ 1383bf215546Sopenharmony_ci user_assert(ppSurface != NULL, D3DERR_INVALIDCALL); 1384bf215546Sopenharmony_ci *ppSurface = NULL; 1385bf215546Sopenharmony_ci if (!depth_stencil_format(Format)) 1386bf215546Sopenharmony_ci return D3DERR_NOTAVAILABLE; 1387bf215546Sopenharmony_ci return create_zs_or_rt_surface(This, 1, D3DPOOL_DEFAULT, 1388bf215546Sopenharmony_ci Width, Height, Format, 1389bf215546Sopenharmony_ci MultiSample, MultisampleQuality, 1390bf215546Sopenharmony_ci Discard, ppSurface, pSharedHandle); 1391bf215546Sopenharmony_ci} 1392bf215546Sopenharmony_ci 1393bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1394bf215546Sopenharmony_ciNineDevice9_UpdateSurface( struct NineDevice9 *This, 1395bf215546Sopenharmony_ci IDirect3DSurface9 *pSourceSurface, 1396bf215546Sopenharmony_ci const RECT *pSourceRect, 1397bf215546Sopenharmony_ci IDirect3DSurface9 *pDestinationSurface, 1398bf215546Sopenharmony_ci const POINT *pDestPoint ) 1399bf215546Sopenharmony_ci{ 1400bf215546Sopenharmony_ci struct NineSurface9 *dst = NineSurface9(pDestinationSurface); 1401bf215546Sopenharmony_ci struct NineSurface9 *src = NineSurface9(pSourceSurface); 1402bf215546Sopenharmony_ci int copy_width, copy_height; 1403bf215546Sopenharmony_ci RECT destRect; 1404bf215546Sopenharmony_ci 1405bf215546Sopenharmony_ci DBG("This=%p pSourceSurface=%p pDestinationSurface=%p " 1406bf215546Sopenharmony_ci "pSourceRect=%p pDestPoint=%p\n", This, 1407bf215546Sopenharmony_ci pSourceSurface, pDestinationSurface, pSourceRect, pDestPoint); 1408bf215546Sopenharmony_ci if (pSourceRect) 1409bf215546Sopenharmony_ci DBG("pSourceRect = (%u,%u)-(%u,%u)\n", 1410bf215546Sopenharmony_ci pSourceRect->left, pSourceRect->top, 1411bf215546Sopenharmony_ci pSourceRect->right, pSourceRect->bottom); 1412bf215546Sopenharmony_ci if (pDestPoint) 1413bf215546Sopenharmony_ci DBG("pDestPoint = (%u,%u)\n", pDestPoint->x, pDestPoint->y); 1414bf215546Sopenharmony_ci 1415bf215546Sopenharmony_ci user_assert(dst && src, D3DERR_INVALIDCALL); 1416bf215546Sopenharmony_ci 1417bf215546Sopenharmony_ci user_assert(dst->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1418bf215546Sopenharmony_ci user_assert(src->base.pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 1419bf215546Sopenharmony_ci 1420bf215546Sopenharmony_ci user_assert(dst->desc.MultiSampleType == D3DMULTISAMPLE_NONE, D3DERR_INVALIDCALL); 1421bf215546Sopenharmony_ci user_assert(src->desc.MultiSampleType == D3DMULTISAMPLE_NONE, D3DERR_INVALIDCALL); 1422bf215546Sopenharmony_ci 1423bf215546Sopenharmony_ci user_assert(!src->lock_count, D3DERR_INVALIDCALL); 1424bf215546Sopenharmony_ci user_assert(!dst->lock_count, D3DERR_INVALIDCALL); 1425bf215546Sopenharmony_ci 1426bf215546Sopenharmony_ci user_assert(dst->desc.Format == src->desc.Format, D3DERR_INVALIDCALL); 1427bf215546Sopenharmony_ci user_assert(!depth_stencil_format(dst->desc.Format), D3DERR_INVALIDCALL); 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci if (pSourceRect) { 1430bf215546Sopenharmony_ci copy_width = pSourceRect->right - pSourceRect->left; 1431bf215546Sopenharmony_ci copy_height = pSourceRect->bottom - pSourceRect->top; 1432bf215546Sopenharmony_ci 1433bf215546Sopenharmony_ci user_assert(pSourceRect->left >= 0 && 1434bf215546Sopenharmony_ci copy_width > 0 && 1435bf215546Sopenharmony_ci pSourceRect->right <= src->desc.Width && 1436bf215546Sopenharmony_ci pSourceRect->top >= 0 && 1437bf215546Sopenharmony_ci copy_height > 0 && 1438bf215546Sopenharmony_ci pSourceRect->bottom <= src->desc.Height, 1439bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1440bf215546Sopenharmony_ci } else { 1441bf215546Sopenharmony_ci copy_width = src->desc.Width; 1442bf215546Sopenharmony_ci copy_height = src->desc.Height; 1443bf215546Sopenharmony_ci } 1444bf215546Sopenharmony_ci 1445bf215546Sopenharmony_ci destRect.right = copy_width; 1446bf215546Sopenharmony_ci destRect.bottom = copy_height; 1447bf215546Sopenharmony_ci 1448bf215546Sopenharmony_ci if (pDestPoint) { 1449bf215546Sopenharmony_ci user_assert(pDestPoint->x >= 0 && pDestPoint->y >= 0, 1450bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1451bf215546Sopenharmony_ci destRect.right += pDestPoint->x; 1452bf215546Sopenharmony_ci destRect.bottom += pDestPoint->y; 1453bf215546Sopenharmony_ci } 1454bf215546Sopenharmony_ci 1455bf215546Sopenharmony_ci user_assert(destRect.right <= dst->desc.Width && 1456bf215546Sopenharmony_ci destRect.bottom <= dst->desc.Height, 1457bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1458bf215546Sopenharmony_ci 1459bf215546Sopenharmony_ci if (compressed_format(dst->desc.Format)) { 1460bf215546Sopenharmony_ci const unsigned w = util_format_get_blockwidth(dst->base.info.format); 1461bf215546Sopenharmony_ci const unsigned h = util_format_get_blockheight(dst->base.info.format); 1462bf215546Sopenharmony_ci 1463bf215546Sopenharmony_ci if (pDestPoint) { 1464bf215546Sopenharmony_ci user_assert(!(pDestPoint->x % w) && !(pDestPoint->y % h), 1465bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1466bf215546Sopenharmony_ci } 1467bf215546Sopenharmony_ci 1468bf215546Sopenharmony_ci if (pSourceRect) { 1469bf215546Sopenharmony_ci user_assert(!(pSourceRect->left % w) && !(pSourceRect->top % h), 1470bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1471bf215546Sopenharmony_ci } 1472bf215546Sopenharmony_ci if (!(copy_width == src->desc.Width && 1473bf215546Sopenharmony_ci copy_width == dst->desc.Width && 1474bf215546Sopenharmony_ci copy_height == src->desc.Height && 1475bf215546Sopenharmony_ci copy_height == dst->desc.Height)) { 1476bf215546Sopenharmony_ci user_assert(!(copy_width % w) && !(copy_height % h), 1477bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1478bf215546Sopenharmony_ci } 1479bf215546Sopenharmony_ci } 1480bf215546Sopenharmony_ci 1481bf215546Sopenharmony_ci NineSurface9_CopyMemToDefault(dst, src, pDestPoint, pSourceRect); 1482bf215546Sopenharmony_ci 1483bf215546Sopenharmony_ci return D3D_OK; 1484bf215546Sopenharmony_ci} 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1487bf215546Sopenharmony_ciNineDevice9_UpdateTexture( struct NineDevice9 *This, 1488bf215546Sopenharmony_ci IDirect3DBaseTexture9 *pSourceTexture, 1489bf215546Sopenharmony_ci IDirect3DBaseTexture9 *pDestinationTexture ) 1490bf215546Sopenharmony_ci{ 1491bf215546Sopenharmony_ci struct NineBaseTexture9 *dstb = NineBaseTexture9(pDestinationTexture); 1492bf215546Sopenharmony_ci struct NineBaseTexture9 *srcb = NineBaseTexture9(pSourceTexture); 1493bf215546Sopenharmony_ci unsigned l, m; 1494bf215546Sopenharmony_ci unsigned last_src_level, last_dst_level; 1495bf215546Sopenharmony_ci RECT rect; 1496bf215546Sopenharmony_ci 1497bf215546Sopenharmony_ci DBG("This=%p pSourceTexture=%p pDestinationTexture=%p\n", This, 1498bf215546Sopenharmony_ci pSourceTexture, pDestinationTexture); 1499bf215546Sopenharmony_ci 1500bf215546Sopenharmony_ci user_assert(pSourceTexture && pDestinationTexture, D3DERR_INVALIDCALL); 1501bf215546Sopenharmony_ci user_assert(pSourceTexture != pDestinationTexture, D3DERR_INVALIDCALL); 1502bf215546Sopenharmony_ci 1503bf215546Sopenharmony_ci user_assert(dstb->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1504bf215546Sopenharmony_ci user_assert(srcb->base.pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 1505bf215546Sopenharmony_ci user_assert(dstb->base.type == srcb->base.type, D3DERR_INVALIDCALL); 1506bf215546Sopenharmony_ci user_assert(!(srcb->base.usage & D3DUSAGE_AUTOGENMIPMAP) || 1507bf215546Sopenharmony_ci dstb->base.usage & D3DUSAGE_AUTOGENMIPMAP, D3DERR_INVALIDCALL); 1508bf215546Sopenharmony_ci 1509bf215546Sopenharmony_ci /* Spec: Failure if 1510bf215546Sopenharmony_ci * . Different formats 1511bf215546Sopenharmony_ci * . Fewer src levels than dst levels (if the opposite, only matching levels 1512bf215546Sopenharmony_ci * are supposed to be copied) 1513bf215546Sopenharmony_ci * . Levels do not match 1514bf215546Sopenharmony_ci * DDI: Actually the above should pass because of legacy applications 1515bf215546Sopenharmony_ci * Do what you want about these, but you shouldn't crash. 1516bf215546Sopenharmony_ci * However driver can expect that the top dimension is greater for src than dst. 1517bf215546Sopenharmony_ci * Wine tests: Every combination that passes the initial checks should pass. 1518bf215546Sopenharmony_ci * . Different formats => conversion driver and format dependent. 1519bf215546Sopenharmony_ci * . 1 level, but size not matching => copy is done (and even crash if src bigger 1520bf215546Sopenharmony_ci * than dst. For the case where dst bigger, wine doesn't test if a stretch is applied 1521bf215546Sopenharmony_ci * or if a subrect is copied). 1522bf215546Sopenharmony_ci * . 8x8 4 sublevels -> 7x7 2 sublevels => driver dependent, On NV seems to be 4x4 subrect 1523bf215546Sopenharmony_ci * copied to 7x7. 1524bf215546Sopenharmony_ci * 1525bf215546Sopenharmony_ci * From these, the proposal is: 1526bf215546Sopenharmony_ci * . Different formats -> use util_format_translate to translate if possible for surfaces. 1527bf215546Sopenharmony_ci * Accept ARGB/XRGB for Volumes. Do nothing for the other combinations 1528bf215546Sopenharmony_ci * . First level copied -> the first level such that src is smaller or equal to dst first level 1529bf215546Sopenharmony_ci * . number of levels copied -> as long as it fits and textures have levels 1530bf215546Sopenharmony_ci * That should satisfy the constraints (and instead of crashing for some cases we return D3D_OK) 1531bf215546Sopenharmony_ci */ 1532bf215546Sopenharmony_ci 1533bf215546Sopenharmony_ci last_src_level = srcb->level_count-1; 1534bf215546Sopenharmony_ci last_dst_level = dstb->level_count-1; 1535bf215546Sopenharmony_ci 1536bf215546Sopenharmony_ci for (m = 0; m <= last_src_level; ++m) { 1537bf215546Sopenharmony_ci unsigned w = u_minify(srcb->base.info.width0, m); 1538bf215546Sopenharmony_ci unsigned h = u_minify(srcb->base.info.height0, m); 1539bf215546Sopenharmony_ci unsigned d = u_minify(srcb->base.info.depth0, m); 1540bf215546Sopenharmony_ci 1541bf215546Sopenharmony_ci if (w <= dstb->base.info.width0 && 1542bf215546Sopenharmony_ci h <= dstb->base.info.height0 && 1543bf215546Sopenharmony_ci d <= dstb->base.info.depth0) 1544bf215546Sopenharmony_ci break; 1545bf215546Sopenharmony_ci } 1546bf215546Sopenharmony_ci user_assert(m <= last_src_level, D3D_OK); 1547bf215546Sopenharmony_ci 1548bf215546Sopenharmony_ci last_dst_level = MIN2(srcb->base.info.last_level - m, last_dst_level); 1549bf215546Sopenharmony_ci 1550bf215546Sopenharmony_ci if (dstb->base.type == D3DRTYPE_TEXTURE) { 1551bf215546Sopenharmony_ci struct NineTexture9 *dst = NineTexture9(dstb); 1552bf215546Sopenharmony_ci struct NineTexture9 *src = NineTexture9(srcb); 1553bf215546Sopenharmony_ci 1554bf215546Sopenharmony_ci if (src->dirty_rect.width == 0) 1555bf215546Sopenharmony_ci return D3D_OK; 1556bf215546Sopenharmony_ci 1557bf215546Sopenharmony_ci pipe_box_to_rect(&rect, &src->dirty_rect); 1558bf215546Sopenharmony_ci for (l = 0; l < m; ++l) 1559bf215546Sopenharmony_ci rect_minify_inclusive(&rect); 1560bf215546Sopenharmony_ci 1561bf215546Sopenharmony_ci for (l = 0; l <= last_dst_level; ++l, ++m) { 1562bf215546Sopenharmony_ci fit_rect_format_inclusive(dst->base.base.info.format, 1563bf215546Sopenharmony_ci &rect, 1564bf215546Sopenharmony_ci dst->surfaces[l]->desc.Width, 1565bf215546Sopenharmony_ci dst->surfaces[l]->desc.Height); 1566bf215546Sopenharmony_ci NineSurface9_CopyMemToDefault(dst->surfaces[l], 1567bf215546Sopenharmony_ci src->surfaces[m], 1568bf215546Sopenharmony_ci (POINT *)&rect, 1569bf215546Sopenharmony_ci &rect); 1570bf215546Sopenharmony_ci rect_minify_inclusive(&rect); 1571bf215546Sopenharmony_ci } 1572bf215546Sopenharmony_ci u_box_origin_2d(0, 0, &src->dirty_rect); 1573bf215546Sopenharmony_ci } else 1574bf215546Sopenharmony_ci if (dstb->base.type == D3DRTYPE_CUBETEXTURE) { 1575bf215546Sopenharmony_ci struct NineCubeTexture9 *dst = NineCubeTexture9(dstb); 1576bf215546Sopenharmony_ci struct NineCubeTexture9 *src = NineCubeTexture9(srcb); 1577bf215546Sopenharmony_ci unsigned z; 1578bf215546Sopenharmony_ci 1579bf215546Sopenharmony_ci /* GPUs usually have them stored as arrays of mip-mapped 2D textures. */ 1580bf215546Sopenharmony_ci for (z = 0; z < 6; ++z) { 1581bf215546Sopenharmony_ci if (src->dirty_rect[z].width == 0) 1582bf215546Sopenharmony_ci continue; 1583bf215546Sopenharmony_ci 1584bf215546Sopenharmony_ci pipe_box_to_rect(&rect, &src->dirty_rect[z]); 1585bf215546Sopenharmony_ci for (l = 0; l < m; ++l) 1586bf215546Sopenharmony_ci rect_minify_inclusive(&rect); 1587bf215546Sopenharmony_ci 1588bf215546Sopenharmony_ci for (l = 0; l <= last_dst_level; ++l, ++m) { 1589bf215546Sopenharmony_ci fit_rect_format_inclusive(dst->base.base.info.format, 1590bf215546Sopenharmony_ci &rect, 1591bf215546Sopenharmony_ci dst->surfaces[l * 6 + z]->desc.Width, 1592bf215546Sopenharmony_ci dst->surfaces[l * 6 + z]->desc.Height); 1593bf215546Sopenharmony_ci NineSurface9_CopyMemToDefault(dst->surfaces[l * 6 + z], 1594bf215546Sopenharmony_ci src->surfaces[m * 6 + z], 1595bf215546Sopenharmony_ci (POINT *)&rect, 1596bf215546Sopenharmony_ci &rect); 1597bf215546Sopenharmony_ci rect_minify_inclusive(&rect); 1598bf215546Sopenharmony_ci } 1599bf215546Sopenharmony_ci u_box_origin_2d(0, 0, &src->dirty_rect[z]); 1600bf215546Sopenharmony_ci m -= l; 1601bf215546Sopenharmony_ci } 1602bf215546Sopenharmony_ci } else 1603bf215546Sopenharmony_ci if (dstb->base.type == D3DRTYPE_VOLUMETEXTURE) { 1604bf215546Sopenharmony_ci struct NineVolumeTexture9 *dst = NineVolumeTexture9(dstb); 1605bf215546Sopenharmony_ci struct NineVolumeTexture9 *src = NineVolumeTexture9(srcb); 1606bf215546Sopenharmony_ci 1607bf215546Sopenharmony_ci if (src->dirty_box.width == 0) 1608bf215546Sopenharmony_ci return D3D_OK; 1609bf215546Sopenharmony_ci for (l = 0; l <= last_dst_level; ++l, ++m) 1610bf215546Sopenharmony_ci NineVolume9_CopyMemToDefault(dst->volumes[l], 1611bf215546Sopenharmony_ci src->volumes[m], 0, 0, 0, NULL); 1612bf215546Sopenharmony_ci u_box_3d(0, 0, 0, 0, 0, 0, &src->dirty_box); 1613bf215546Sopenharmony_ci } else{ 1614bf215546Sopenharmony_ci assert(!"invalid texture type"); 1615bf215546Sopenharmony_ci } 1616bf215546Sopenharmony_ci 1617bf215546Sopenharmony_ci if (dstb->base.usage & D3DUSAGE_AUTOGENMIPMAP) { 1618bf215546Sopenharmony_ci dstb->dirty_mip = TRUE; 1619bf215546Sopenharmony_ci NineBaseTexture9_GenerateMipSubLevels(dstb); 1620bf215546Sopenharmony_ci } 1621bf215546Sopenharmony_ci 1622bf215546Sopenharmony_ci return D3D_OK; 1623bf215546Sopenharmony_ci} 1624bf215546Sopenharmony_ci 1625bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1626bf215546Sopenharmony_ciNineDevice9_GetRenderTargetData( struct NineDevice9 *This, 1627bf215546Sopenharmony_ci IDirect3DSurface9 *pRenderTarget, 1628bf215546Sopenharmony_ci IDirect3DSurface9 *pDestSurface ) 1629bf215546Sopenharmony_ci{ 1630bf215546Sopenharmony_ci struct NineSurface9 *dst = NineSurface9(pDestSurface); 1631bf215546Sopenharmony_ci struct NineSurface9 *src = NineSurface9(pRenderTarget); 1632bf215546Sopenharmony_ci 1633bf215546Sopenharmony_ci DBG("This=%p pRenderTarget=%p pDestSurface=%p\n", 1634bf215546Sopenharmony_ci This, pRenderTarget, pDestSurface); 1635bf215546Sopenharmony_ci 1636bf215546Sopenharmony_ci user_assert(pRenderTarget && pDestSurface, D3DERR_INVALIDCALL); 1637bf215546Sopenharmony_ci 1638bf215546Sopenharmony_ci user_assert(dst->desc.Pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 1639bf215546Sopenharmony_ci user_assert(src->desc.Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1640bf215546Sopenharmony_ci 1641bf215546Sopenharmony_ci user_assert(dst->desc.MultiSampleType < 2, D3DERR_INVALIDCALL); 1642bf215546Sopenharmony_ci user_assert(src->desc.MultiSampleType < 2, D3DERR_INVALIDCALL); 1643bf215546Sopenharmony_ci 1644bf215546Sopenharmony_ci user_assert(src->desc.Width == dst->desc.Width, D3DERR_INVALIDCALL); 1645bf215546Sopenharmony_ci user_assert(src->desc.Height == dst->desc.Height, D3DERR_INVALIDCALL); 1646bf215546Sopenharmony_ci 1647bf215546Sopenharmony_ci user_assert(src->desc.Format != D3DFMT_NULL, D3DERR_INVALIDCALL); 1648bf215546Sopenharmony_ci 1649bf215546Sopenharmony_ci NineSurface9_CopyDefaultToMem(dst, src); 1650bf215546Sopenharmony_ci 1651bf215546Sopenharmony_ci return D3D_OK; 1652bf215546Sopenharmony_ci} 1653bf215546Sopenharmony_ci 1654bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1655bf215546Sopenharmony_ciNineDevice9_GetFrontBufferData( struct NineDevice9 *This, 1656bf215546Sopenharmony_ci UINT iSwapChain, 1657bf215546Sopenharmony_ci IDirect3DSurface9 *pDestSurface ) 1658bf215546Sopenharmony_ci{ 1659bf215546Sopenharmony_ci DBG("This=%p iSwapChain=%u pDestSurface=%p\n", This, 1660bf215546Sopenharmony_ci iSwapChain, pDestSurface); 1661bf215546Sopenharmony_ci 1662bf215546Sopenharmony_ci user_assert(pDestSurface != NULL, D3DERR_INVALIDCALL); 1663bf215546Sopenharmony_ci user_assert(iSwapChain < This->nswapchains, D3DERR_INVALIDCALL); 1664bf215546Sopenharmony_ci 1665bf215546Sopenharmony_ci return NineSwapChain9_GetFrontBufferData(This->swapchains[iSwapChain], 1666bf215546Sopenharmony_ci pDestSurface); 1667bf215546Sopenharmony_ci} 1668bf215546Sopenharmony_ci 1669bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1670bf215546Sopenharmony_ciNineDevice9_StretchRect( struct NineDevice9 *This, 1671bf215546Sopenharmony_ci IDirect3DSurface9 *pSourceSurface, 1672bf215546Sopenharmony_ci const RECT *pSourceRect, 1673bf215546Sopenharmony_ci IDirect3DSurface9 *pDestSurface, 1674bf215546Sopenharmony_ci const RECT *pDestRect, 1675bf215546Sopenharmony_ci D3DTEXTUREFILTERTYPE Filter ) 1676bf215546Sopenharmony_ci{ 1677bf215546Sopenharmony_ci struct pipe_screen *screen = This->screen; 1678bf215546Sopenharmony_ci struct NineSurface9 *dst = NineSurface9(pDestSurface); 1679bf215546Sopenharmony_ci struct NineSurface9 *src = NineSurface9(pSourceSurface); 1680bf215546Sopenharmony_ci struct pipe_resource *dst_res, *src_res; 1681bf215546Sopenharmony_ci boolean zs; 1682bf215546Sopenharmony_ci struct pipe_blit_info blit; 1683bf215546Sopenharmony_ci boolean scaled, clamped, ms, flip_x = FALSE, flip_y = FALSE; 1684bf215546Sopenharmony_ci 1685bf215546Sopenharmony_ci DBG("This=%p pSourceSurface=%p pSourceRect=%p pDestSurface=%p " 1686bf215546Sopenharmony_ci "pDestRect=%p Filter=%u\n", 1687bf215546Sopenharmony_ci This, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter); 1688bf215546Sopenharmony_ci if (pSourceRect) 1689bf215546Sopenharmony_ci DBG("pSourceRect=(%u,%u)-(%u,%u)\n", 1690bf215546Sopenharmony_ci pSourceRect->left, pSourceRect->top, 1691bf215546Sopenharmony_ci pSourceRect->right, pSourceRect->bottom); 1692bf215546Sopenharmony_ci if (pDestRect) 1693bf215546Sopenharmony_ci DBG("pDestRect=(%u,%u)-(%u,%u)\n", pDestRect->left, pDestRect->top, 1694bf215546Sopenharmony_ci pDestRect->right, pDestRect->bottom); 1695bf215546Sopenharmony_ci 1696bf215546Sopenharmony_ci user_assert(pSourceSurface && pDestSurface, D3DERR_INVALIDCALL); 1697bf215546Sopenharmony_ci user_assert(dst->base.pool == D3DPOOL_DEFAULT && 1698bf215546Sopenharmony_ci src->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1699bf215546Sopenharmony_ci 1700bf215546Sopenharmony_ci dst_res = NineSurface9_GetResource(dst); 1701bf215546Sopenharmony_ci src_res = NineSurface9_GetResource(src); 1702bf215546Sopenharmony_ci zs = util_format_is_depth_or_stencil(dst_res->format); 1703bf215546Sopenharmony_ci user_assert(!zs || !This->in_scene, D3DERR_INVALIDCALL); 1704bf215546Sopenharmony_ci user_assert(!zs || !pSourceRect || 1705bf215546Sopenharmony_ci (pSourceRect->left == 0 && 1706bf215546Sopenharmony_ci pSourceRect->top == 0 && 1707bf215546Sopenharmony_ci pSourceRect->right == src->desc.Width && 1708bf215546Sopenharmony_ci pSourceRect->bottom == src->desc.Height), D3DERR_INVALIDCALL); 1709bf215546Sopenharmony_ci user_assert(!zs || !pDestRect || 1710bf215546Sopenharmony_ci (pDestRect->left == 0 && 1711bf215546Sopenharmony_ci pDestRect->top == 0 && 1712bf215546Sopenharmony_ci pDestRect->right == dst->desc.Width && 1713bf215546Sopenharmony_ci pDestRect->bottom == dst->desc.Height), D3DERR_INVALIDCALL); 1714bf215546Sopenharmony_ci user_assert(!zs || 1715bf215546Sopenharmony_ci (dst->desc.Width == src->desc.Width && 1716bf215546Sopenharmony_ci dst->desc.Height == src->desc.Height), D3DERR_INVALIDCALL); 1717bf215546Sopenharmony_ci user_assert(zs || !util_format_is_depth_or_stencil(src_res->format), 1718bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1719bf215546Sopenharmony_ci user_assert(!zs || dst->desc.Format == src->desc.Format, 1720bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1721bf215546Sopenharmony_ci user_assert(screen->is_format_supported(screen, src_res->format, 1722bf215546Sopenharmony_ci src_res->target, 1723bf215546Sopenharmony_ci src_res->nr_samples, 1724bf215546Sopenharmony_ci src_res->nr_storage_samples, 1725bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW), 1726bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1727bf215546Sopenharmony_ci 1728bf215546Sopenharmony_ci /* We might want to permit these, but wine thinks we shouldn't. */ 1729bf215546Sopenharmony_ci user_assert(!pDestRect || 1730bf215546Sopenharmony_ci (pDestRect->left <= pDestRect->right && 1731bf215546Sopenharmony_ci pDestRect->top <= pDestRect->bottom), D3DERR_INVALIDCALL); 1732bf215546Sopenharmony_ci user_assert(!pSourceRect || 1733bf215546Sopenharmony_ci (pSourceRect->left <= pSourceRect->right && 1734bf215546Sopenharmony_ci pSourceRect->top <= pSourceRect->bottom), D3DERR_INVALIDCALL); 1735bf215546Sopenharmony_ci 1736bf215546Sopenharmony_ci memset(&blit, 0, sizeof(blit)); 1737bf215546Sopenharmony_ci blit.dst.resource = dst_res; 1738bf215546Sopenharmony_ci blit.dst.level = dst->level; 1739bf215546Sopenharmony_ci blit.dst.box.z = dst->layer; 1740bf215546Sopenharmony_ci blit.dst.box.depth = 1; 1741bf215546Sopenharmony_ci blit.dst.format = dst_res->format; 1742bf215546Sopenharmony_ci if (pDestRect) { 1743bf215546Sopenharmony_ci flip_x = pDestRect->left > pDestRect->right; 1744bf215546Sopenharmony_ci if (flip_x) { 1745bf215546Sopenharmony_ci blit.dst.box.x = pDestRect->right; 1746bf215546Sopenharmony_ci blit.dst.box.width = pDestRect->left - pDestRect->right; 1747bf215546Sopenharmony_ci } else { 1748bf215546Sopenharmony_ci blit.dst.box.x = pDestRect->left; 1749bf215546Sopenharmony_ci blit.dst.box.width = pDestRect->right - pDestRect->left; 1750bf215546Sopenharmony_ci } 1751bf215546Sopenharmony_ci flip_y = pDestRect->top > pDestRect->bottom; 1752bf215546Sopenharmony_ci if (flip_y) { 1753bf215546Sopenharmony_ci blit.dst.box.y = pDestRect->bottom; 1754bf215546Sopenharmony_ci blit.dst.box.height = pDestRect->top - pDestRect->bottom; 1755bf215546Sopenharmony_ci } else { 1756bf215546Sopenharmony_ci blit.dst.box.y = pDestRect->top; 1757bf215546Sopenharmony_ci blit.dst.box.height = pDestRect->bottom - pDestRect->top; 1758bf215546Sopenharmony_ci } 1759bf215546Sopenharmony_ci } else { 1760bf215546Sopenharmony_ci blit.dst.box.x = 0; 1761bf215546Sopenharmony_ci blit.dst.box.y = 0; 1762bf215546Sopenharmony_ci blit.dst.box.width = dst->desc.Width; 1763bf215546Sopenharmony_ci blit.dst.box.height = dst->desc.Height; 1764bf215546Sopenharmony_ci } 1765bf215546Sopenharmony_ci blit.src.resource = src_res; 1766bf215546Sopenharmony_ci blit.src.level = src->level; 1767bf215546Sopenharmony_ci blit.src.box.z = src->layer; 1768bf215546Sopenharmony_ci blit.src.box.depth = 1; 1769bf215546Sopenharmony_ci blit.src.format = src_res->format; 1770bf215546Sopenharmony_ci if (pSourceRect) { 1771bf215546Sopenharmony_ci if (flip_x ^ (pSourceRect->left > pSourceRect->right)) { 1772bf215546Sopenharmony_ci blit.src.box.x = pSourceRect->right; 1773bf215546Sopenharmony_ci blit.src.box.width = pSourceRect->left - pSourceRect->right; 1774bf215546Sopenharmony_ci } else { 1775bf215546Sopenharmony_ci blit.src.box.x = pSourceRect->left; 1776bf215546Sopenharmony_ci blit.src.box.width = pSourceRect->right - pSourceRect->left; 1777bf215546Sopenharmony_ci } 1778bf215546Sopenharmony_ci if (flip_y ^ (pSourceRect->top > pSourceRect->bottom)) { 1779bf215546Sopenharmony_ci blit.src.box.y = pSourceRect->bottom; 1780bf215546Sopenharmony_ci blit.src.box.height = pSourceRect->top - pSourceRect->bottom; 1781bf215546Sopenharmony_ci } else { 1782bf215546Sopenharmony_ci blit.src.box.y = pSourceRect->top; 1783bf215546Sopenharmony_ci blit.src.box.height = pSourceRect->bottom - pSourceRect->top; 1784bf215546Sopenharmony_ci } 1785bf215546Sopenharmony_ci } else { 1786bf215546Sopenharmony_ci blit.src.box.x = flip_x ? src->desc.Width : 0; 1787bf215546Sopenharmony_ci blit.src.box.y = flip_y ? src->desc.Height : 0; 1788bf215546Sopenharmony_ci blit.src.box.width = flip_x ? -src->desc.Width : src->desc.Width; 1789bf215546Sopenharmony_ci blit.src.box.height = flip_y ? -src->desc.Height : src->desc.Height; 1790bf215546Sopenharmony_ci } 1791bf215546Sopenharmony_ci blit.mask = zs ? PIPE_MASK_ZS : PIPE_MASK_RGBA; 1792bf215546Sopenharmony_ci blit.filter = Filter == D3DTEXF_LINEAR ? 1793bf215546Sopenharmony_ci PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST; 1794bf215546Sopenharmony_ci blit.scissor_enable = FALSE; 1795bf215546Sopenharmony_ci blit.alpha_blend = FALSE; 1796bf215546Sopenharmony_ci 1797bf215546Sopenharmony_ci /* If both of a src and dst dimension are negative, flip them. */ 1798bf215546Sopenharmony_ci if (blit.dst.box.width < 0 && blit.src.box.width < 0) { 1799bf215546Sopenharmony_ci blit.dst.box.width = -blit.dst.box.width; 1800bf215546Sopenharmony_ci blit.src.box.width = -blit.src.box.width; 1801bf215546Sopenharmony_ci } 1802bf215546Sopenharmony_ci if (blit.dst.box.height < 0 && blit.src.box.height < 0) { 1803bf215546Sopenharmony_ci blit.dst.box.height = -blit.dst.box.height; 1804bf215546Sopenharmony_ci blit.src.box.height = -blit.src.box.height; 1805bf215546Sopenharmony_ci } 1806bf215546Sopenharmony_ci scaled = 1807bf215546Sopenharmony_ci blit.dst.box.width != blit.src.box.width || 1808bf215546Sopenharmony_ci blit.dst.box.height != blit.src.box.height; 1809bf215546Sopenharmony_ci 1810bf215546Sopenharmony_ci user_assert(!scaled || dst != src, D3DERR_INVALIDCALL); 1811bf215546Sopenharmony_ci user_assert(!scaled || 1812bf215546Sopenharmony_ci !NineSurface9_IsOffscreenPlain(dst), D3DERR_INVALIDCALL); 1813bf215546Sopenharmony_ci user_assert(!NineSurface9_IsOffscreenPlain(dst) || 1814bf215546Sopenharmony_ci NineSurface9_IsOffscreenPlain(src), D3DERR_INVALIDCALL); 1815bf215546Sopenharmony_ci user_assert(NineSurface9_IsOffscreenPlain(dst) || 1816bf215546Sopenharmony_ci dst->desc.Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL), 1817bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1818bf215546Sopenharmony_ci user_assert(!scaled || 1819bf215546Sopenharmony_ci (!util_format_is_compressed(dst->base.info.format) && 1820bf215546Sopenharmony_ci !util_format_is_compressed(src->base.info.format)), 1821bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1822bf215546Sopenharmony_ci 1823bf215546Sopenharmony_ci user_warn(src == dst && 1824bf215546Sopenharmony_ci u_box_test_intersection_2d(&blit.src.box, &blit.dst.box)); 1825bf215546Sopenharmony_ci 1826bf215546Sopenharmony_ci /* Check for clipping/clamping: */ 1827bf215546Sopenharmony_ci { 1828bf215546Sopenharmony_ci struct pipe_box box; 1829bf215546Sopenharmony_ci int xy; 1830bf215546Sopenharmony_ci 1831bf215546Sopenharmony_ci xy = u_box_clip_2d(&box, &blit.dst.box, 1832bf215546Sopenharmony_ci dst->desc.Width, dst->desc.Height); 1833bf215546Sopenharmony_ci if (xy < 0) 1834bf215546Sopenharmony_ci return D3D_OK; 1835bf215546Sopenharmony_ci if (xy == 0) 1836bf215546Sopenharmony_ci xy = u_box_clip_2d(&box, &blit.src.box, 1837bf215546Sopenharmony_ci src->desc.Width, src->desc.Height); 1838bf215546Sopenharmony_ci clamped = !!xy; 1839bf215546Sopenharmony_ci } 1840bf215546Sopenharmony_ci 1841bf215546Sopenharmony_ci ms = (dst->desc.MultiSampleType != src->desc.MultiSampleType) || 1842bf215546Sopenharmony_ci (dst->desc.MultiSampleQuality != src->desc.MultiSampleQuality); 1843bf215546Sopenharmony_ci 1844bf215546Sopenharmony_ci if (clamped || scaled || (blit.dst.format != blit.src.format) || ms) { 1845bf215546Sopenharmony_ci DBG("using pipe->blit()\n"); 1846bf215546Sopenharmony_ci /* TODO: software scaling */ 1847bf215546Sopenharmony_ci user_assert(screen->is_format_supported(screen, dst_res->format, 1848bf215546Sopenharmony_ci dst_res->target, 1849bf215546Sopenharmony_ci dst_res->nr_samples, 1850bf215546Sopenharmony_ci dst_res->nr_storage_samples, 1851bf215546Sopenharmony_ci zs ? PIPE_BIND_DEPTH_STENCIL : 1852bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET), 1853bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1854bf215546Sopenharmony_ci 1855bf215546Sopenharmony_ci nine_context_blit(This, (struct NineUnknown *)dst, 1856bf215546Sopenharmony_ci (struct NineUnknown *)src, &blit); 1857bf215546Sopenharmony_ci } else { 1858bf215546Sopenharmony_ci assert(blit.dst.box.x >= 0 && blit.dst.box.y >= 0 && 1859bf215546Sopenharmony_ci blit.src.box.x >= 0 && blit.src.box.y >= 0 && 1860bf215546Sopenharmony_ci blit.dst.box.x + blit.dst.box.width <= dst->desc.Width && 1861bf215546Sopenharmony_ci blit.src.box.x + blit.src.box.width <= src->desc.Width && 1862bf215546Sopenharmony_ci blit.dst.box.y + blit.dst.box.height <= dst->desc.Height && 1863bf215546Sopenharmony_ci blit.src.box.y + blit.src.box.height <= src->desc.Height); 1864bf215546Sopenharmony_ci /* Or drivers might crash ... */ 1865bf215546Sopenharmony_ci DBG("Using resource_copy_region.\n"); 1866bf215546Sopenharmony_ci nine_context_resource_copy_region(This, (struct NineUnknown *)dst, 1867bf215546Sopenharmony_ci (struct NineUnknown *)src, 1868bf215546Sopenharmony_ci blit.dst.resource, blit.dst.level, 1869bf215546Sopenharmony_ci &blit.dst.box, 1870bf215546Sopenharmony_ci blit.src.resource, blit.src.level, 1871bf215546Sopenharmony_ci &blit.src.box); 1872bf215546Sopenharmony_ci } 1873bf215546Sopenharmony_ci 1874bf215546Sopenharmony_ci /* Communicate the container it needs to update sublevels - if apply */ 1875bf215546Sopenharmony_ci NineSurface9_MarkContainerDirty(dst); 1876bf215546Sopenharmony_ci 1877bf215546Sopenharmony_ci return D3D_OK; 1878bf215546Sopenharmony_ci} 1879bf215546Sopenharmony_ci 1880bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1881bf215546Sopenharmony_ciNineDevice9_ColorFill( struct NineDevice9 *This, 1882bf215546Sopenharmony_ci IDirect3DSurface9 *pSurface, 1883bf215546Sopenharmony_ci const RECT *pRect, 1884bf215546Sopenharmony_ci D3DCOLOR color ) 1885bf215546Sopenharmony_ci{ 1886bf215546Sopenharmony_ci struct NineSurface9 *surf = NineSurface9(pSurface); 1887bf215546Sopenharmony_ci unsigned x, y, w, h; 1888bf215546Sopenharmony_ci 1889bf215546Sopenharmony_ci DBG("This=%p pSurface=%p pRect=%p color=%08x\n", This, 1890bf215546Sopenharmony_ci pSurface, pRect, color); 1891bf215546Sopenharmony_ci if (pRect) 1892bf215546Sopenharmony_ci DBG("pRect=(%u,%u)-(%u,%u)\n", pRect->left, pRect->top, 1893bf215546Sopenharmony_ci pRect->right, pRect->bottom); 1894bf215546Sopenharmony_ci 1895bf215546Sopenharmony_ci user_assert(pSurface != NULL, D3DERR_INVALIDCALL); 1896bf215546Sopenharmony_ci 1897bf215546Sopenharmony_ci user_assert(surf->base.pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); 1898bf215546Sopenharmony_ci 1899bf215546Sopenharmony_ci user_assert((surf->base.usage & D3DUSAGE_RENDERTARGET) || 1900bf215546Sopenharmony_ci NineSurface9_IsOffscreenPlain(surf), D3DERR_INVALIDCALL); 1901bf215546Sopenharmony_ci 1902bf215546Sopenharmony_ci user_assert(surf->desc.Format != D3DFMT_NULL, D3D_OK); 1903bf215546Sopenharmony_ci 1904bf215546Sopenharmony_ci if (pRect) { 1905bf215546Sopenharmony_ci x = pRect->left; 1906bf215546Sopenharmony_ci y = pRect->top; 1907bf215546Sopenharmony_ci w = pRect->right - pRect->left; 1908bf215546Sopenharmony_ci h = pRect->bottom - pRect->top; 1909bf215546Sopenharmony_ci /* Wine tests: */ 1910bf215546Sopenharmony_ci if (compressed_format(surf->desc.Format)) { 1911bf215546Sopenharmony_ci const unsigned bw = util_format_get_blockwidth(surf->base.info.format); 1912bf215546Sopenharmony_ci const unsigned bh = util_format_get_blockheight(surf->base.info.format); 1913bf215546Sopenharmony_ci 1914bf215546Sopenharmony_ci user_assert(!(x % bw) && !(y % bh) && !(w % bw) && !(h % bh), 1915bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 1916bf215546Sopenharmony_ci } 1917bf215546Sopenharmony_ci } else{ 1918bf215546Sopenharmony_ci x = 0; 1919bf215546Sopenharmony_ci y = 0; 1920bf215546Sopenharmony_ci w = surf->desc.Width; 1921bf215546Sopenharmony_ci h = surf->desc.Height; 1922bf215546Sopenharmony_ci } 1923bf215546Sopenharmony_ci 1924bf215546Sopenharmony_ci if (surf->base.info.bind & PIPE_BIND_RENDER_TARGET) { 1925bf215546Sopenharmony_ci nine_context_clear_render_target(This, surf, color, x, y, w, h); 1926bf215546Sopenharmony_ci } else { 1927bf215546Sopenharmony_ci D3DLOCKED_RECT lock; 1928bf215546Sopenharmony_ci union util_color uc; 1929bf215546Sopenharmony_ci HRESULT hr; 1930bf215546Sopenharmony_ci /* XXX: lock pRect and fix util_fill_rect */ 1931bf215546Sopenharmony_ci hr = NineSurface9_LockRect(surf, &lock, NULL, pRect ? 0 : D3DLOCK_DISCARD); 1932bf215546Sopenharmony_ci if (FAILED(hr)) 1933bf215546Sopenharmony_ci return hr; 1934bf215546Sopenharmony_ci util_pack_color_ub(color >> 16, color >> 8, color >> 0, color >> 24, 1935bf215546Sopenharmony_ci surf->base.info.format, &uc); 1936bf215546Sopenharmony_ci util_fill_rect(lock.pBits, surf->base.info.format,lock.Pitch, 1937bf215546Sopenharmony_ci x, y, w, h, &uc); 1938bf215546Sopenharmony_ci NineSurface9_UnlockRect(surf); 1939bf215546Sopenharmony_ci } 1940bf215546Sopenharmony_ci 1941bf215546Sopenharmony_ci return D3D_OK; 1942bf215546Sopenharmony_ci} 1943bf215546Sopenharmony_ci 1944bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1945bf215546Sopenharmony_ciNineDevice9_CreateOffscreenPlainSurface( struct NineDevice9 *This, 1946bf215546Sopenharmony_ci UINT Width, 1947bf215546Sopenharmony_ci UINT Height, 1948bf215546Sopenharmony_ci D3DFORMAT Format, 1949bf215546Sopenharmony_ci D3DPOOL Pool, 1950bf215546Sopenharmony_ci IDirect3DSurface9 **ppSurface, 1951bf215546Sopenharmony_ci HANDLE *pSharedHandle ) 1952bf215546Sopenharmony_ci{ 1953bf215546Sopenharmony_ci HRESULT hr; 1954bf215546Sopenharmony_ci 1955bf215546Sopenharmony_ci DBG("This=%p Width=%u Height=%u Format=%s(0x%x) Pool=%u " 1956bf215546Sopenharmony_ci "ppSurface=%p pSharedHandle=%p\n", This, 1957bf215546Sopenharmony_ci Width, Height, d3dformat_to_string(Format), Format, Pool, 1958bf215546Sopenharmony_ci ppSurface, pSharedHandle); 1959bf215546Sopenharmony_ci 1960bf215546Sopenharmony_ci user_assert(ppSurface != NULL, D3DERR_INVALIDCALL); 1961bf215546Sopenharmony_ci *ppSurface = NULL; 1962bf215546Sopenharmony_ci user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT 1963bf215546Sopenharmony_ci || Pool == D3DPOOL_SYSTEMMEM, D3DERR_INVALIDCALL); 1964bf215546Sopenharmony_ci user_assert(Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL); 1965bf215546Sopenharmony_ci 1966bf215546Sopenharmony_ci /* Can be used with StretchRect and ColorFill. It's also always lockable. 1967bf215546Sopenharmony_ci */ 1968bf215546Sopenharmony_ci hr = create_zs_or_rt_surface(This, 2, Pool, Width, Height, 1969bf215546Sopenharmony_ci Format, 1970bf215546Sopenharmony_ci D3DMULTISAMPLE_NONE, 0, 1971bf215546Sopenharmony_ci TRUE, 1972bf215546Sopenharmony_ci ppSurface, pSharedHandle); 1973bf215546Sopenharmony_ci if (FAILED(hr)) 1974bf215546Sopenharmony_ci DBG("Failed to create surface.\n"); 1975bf215546Sopenharmony_ci return hr; 1976bf215546Sopenharmony_ci} 1977bf215546Sopenharmony_ci 1978bf215546Sopenharmony_ciHRESULT NINE_WINAPI 1979bf215546Sopenharmony_ciNineDevice9_SetRenderTarget( struct NineDevice9 *This, 1980bf215546Sopenharmony_ci DWORD RenderTargetIndex, 1981bf215546Sopenharmony_ci IDirect3DSurface9 *pRenderTarget ) 1982bf215546Sopenharmony_ci{ 1983bf215546Sopenharmony_ci struct NineSurface9 *rt = NineSurface9(pRenderTarget); 1984bf215546Sopenharmony_ci const unsigned i = RenderTargetIndex; 1985bf215546Sopenharmony_ci 1986bf215546Sopenharmony_ci DBG("This=%p RenderTargetIndex=%u pRenderTarget=%p\n", This, 1987bf215546Sopenharmony_ci RenderTargetIndex, pRenderTarget); 1988bf215546Sopenharmony_ci 1989bf215546Sopenharmony_ci user_assert(i < This->caps.NumSimultaneousRTs, D3DERR_INVALIDCALL); 1990bf215546Sopenharmony_ci user_assert(i != 0 || pRenderTarget, D3DERR_INVALIDCALL); 1991bf215546Sopenharmony_ci user_assert(!pRenderTarget || 1992bf215546Sopenharmony_ci rt->desc.Usage & D3DUSAGE_RENDERTARGET, D3DERR_INVALIDCALL); 1993bf215546Sopenharmony_ci 1994bf215546Sopenharmony_ci if (i == 0) { 1995bf215546Sopenharmony_ci This->state.viewport.X = 0; 1996bf215546Sopenharmony_ci This->state.viewport.Y = 0; 1997bf215546Sopenharmony_ci This->state.viewport.Width = rt->desc.Width; 1998bf215546Sopenharmony_ci This->state.viewport.Height = rt->desc.Height; 1999bf215546Sopenharmony_ci This->state.viewport.MinZ = 0.0f; 2000bf215546Sopenharmony_ci This->state.viewport.MaxZ = 1.0f; 2001bf215546Sopenharmony_ci 2002bf215546Sopenharmony_ci This->state.scissor.minx = 0; 2003bf215546Sopenharmony_ci This->state.scissor.miny = 0; 2004bf215546Sopenharmony_ci This->state.scissor.maxx = rt->desc.Width; 2005bf215546Sopenharmony_ci This->state.scissor.maxy = rt->desc.Height; 2006bf215546Sopenharmony_ci nine_context_set_viewport(This, &This->state.viewport); 2007bf215546Sopenharmony_ci nine_context_set_scissor(This, &This->state.scissor); 2008bf215546Sopenharmony_ci } 2009bf215546Sopenharmony_ci 2010bf215546Sopenharmony_ci if (This->state.rt[i] != NineSurface9(pRenderTarget)) 2011bf215546Sopenharmony_ci nine_bind(&This->state.rt[i], pRenderTarget); 2012bf215546Sopenharmony_ci 2013bf215546Sopenharmony_ci nine_context_set_render_target(This, i, rt); 2014bf215546Sopenharmony_ci return D3D_OK; 2015bf215546Sopenharmony_ci} 2016bf215546Sopenharmony_ci 2017bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2018bf215546Sopenharmony_ciNineDevice9_GetRenderTarget( struct NineDevice9 *This, 2019bf215546Sopenharmony_ci DWORD RenderTargetIndex, 2020bf215546Sopenharmony_ci IDirect3DSurface9 **ppRenderTarget ) 2021bf215546Sopenharmony_ci{ 2022bf215546Sopenharmony_ci const unsigned i = RenderTargetIndex; 2023bf215546Sopenharmony_ci 2024bf215546Sopenharmony_ci user_assert(i < This->caps.NumSimultaneousRTs, D3DERR_INVALIDCALL); 2025bf215546Sopenharmony_ci user_assert(ppRenderTarget, D3DERR_INVALIDCALL); 2026bf215546Sopenharmony_ci 2027bf215546Sopenharmony_ci *ppRenderTarget = (IDirect3DSurface9 *)This->state.rt[i]; 2028bf215546Sopenharmony_ci if (!This->state.rt[i]) 2029bf215546Sopenharmony_ci return D3DERR_NOTFOUND; 2030bf215546Sopenharmony_ci 2031bf215546Sopenharmony_ci NineUnknown_AddRef(NineUnknown(This->state.rt[i])); 2032bf215546Sopenharmony_ci return D3D_OK; 2033bf215546Sopenharmony_ci} 2034bf215546Sopenharmony_ci 2035bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2036bf215546Sopenharmony_ciNineDevice9_SetDepthStencilSurface( struct NineDevice9 *This, 2037bf215546Sopenharmony_ci IDirect3DSurface9 *pNewZStencil ) 2038bf215546Sopenharmony_ci{ 2039bf215546Sopenharmony_ci struct NineSurface9 *ds = NineSurface9(pNewZStencil); 2040bf215546Sopenharmony_ci DBG("This=%p pNewZStencil=%p\n", This, pNewZStencil); 2041bf215546Sopenharmony_ci 2042bf215546Sopenharmony_ci user_assert(!ds || util_format_is_depth_or_stencil(ds->base.info.format), 2043bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 2044bf215546Sopenharmony_ci 2045bf215546Sopenharmony_ci if (This->state.ds != ds) { 2046bf215546Sopenharmony_ci nine_bind(&This->state.ds, ds); 2047bf215546Sopenharmony_ci nine_context_set_depth_stencil(This, ds); 2048bf215546Sopenharmony_ci } 2049bf215546Sopenharmony_ci return D3D_OK; 2050bf215546Sopenharmony_ci} 2051bf215546Sopenharmony_ci 2052bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2053bf215546Sopenharmony_ciNineDevice9_GetDepthStencilSurface( struct NineDevice9 *This, 2054bf215546Sopenharmony_ci IDirect3DSurface9 **ppZStencilSurface ) 2055bf215546Sopenharmony_ci{ 2056bf215546Sopenharmony_ci user_assert(ppZStencilSurface, D3DERR_INVALIDCALL); 2057bf215546Sopenharmony_ci 2058bf215546Sopenharmony_ci *ppZStencilSurface = (IDirect3DSurface9 *)This->state.ds; 2059bf215546Sopenharmony_ci if (!This->state.ds) 2060bf215546Sopenharmony_ci return D3DERR_NOTFOUND; 2061bf215546Sopenharmony_ci 2062bf215546Sopenharmony_ci NineUnknown_AddRef(NineUnknown(This->state.ds)); 2063bf215546Sopenharmony_ci return D3D_OK; 2064bf215546Sopenharmony_ci} 2065bf215546Sopenharmony_ci 2066bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2067bf215546Sopenharmony_ciNineDevice9_BeginScene( struct NineDevice9 *This ) 2068bf215546Sopenharmony_ci{ 2069bf215546Sopenharmony_ci DBG("This=%p\n", This); 2070bf215546Sopenharmony_ci user_assert(!This->in_scene, D3DERR_INVALIDCALL); 2071bf215546Sopenharmony_ci This->in_scene = TRUE; 2072bf215546Sopenharmony_ci /* Do we want to do anything else here ? */ 2073bf215546Sopenharmony_ci return D3D_OK; 2074bf215546Sopenharmony_ci} 2075bf215546Sopenharmony_ci 2076bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2077bf215546Sopenharmony_ciNineDevice9_EndScene( struct NineDevice9 *This ) 2078bf215546Sopenharmony_ci{ 2079bf215546Sopenharmony_ci DBG("This=%p\n", This); 2080bf215546Sopenharmony_ci user_assert(This->in_scene, D3DERR_INVALIDCALL); 2081bf215546Sopenharmony_ci This->in_scene = FALSE; 2082bf215546Sopenharmony_ci This->end_scene_since_present++; 2083bf215546Sopenharmony_ci /* EndScene() is supposed to flush the GPU commands. 2084bf215546Sopenharmony_ci * The idea is to flush ahead of the Present() call. 2085bf215546Sopenharmony_ci * (Apps could take advantage of this by inserting CPU 2086bf215546Sopenharmony_ci * work between EndScene() and Present()). 2087bf215546Sopenharmony_ci * Most apps will have one EndScene per frame. 2088bf215546Sopenharmony_ci * Some will have 2 or 3. 2089bf215546Sopenharmony_ci * Some bad behaving apps do a lot of them. 2090bf215546Sopenharmony_ci * As flushing has a cost, do it only once. */ 2091bf215546Sopenharmony_ci if (This->end_scene_since_present <= 1) { 2092bf215546Sopenharmony_ci nine_context_pipe_flush(This); 2093bf215546Sopenharmony_ci nine_csmt_flush(This); 2094bf215546Sopenharmony_ci } 2095bf215546Sopenharmony_ci return D3D_OK; 2096bf215546Sopenharmony_ci} 2097bf215546Sopenharmony_ci 2098bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2099bf215546Sopenharmony_ciNineDevice9_Clear( struct NineDevice9 *This, 2100bf215546Sopenharmony_ci DWORD Count, 2101bf215546Sopenharmony_ci const D3DRECT *pRects, 2102bf215546Sopenharmony_ci DWORD Flags, 2103bf215546Sopenharmony_ci D3DCOLOR Color, 2104bf215546Sopenharmony_ci float Z, 2105bf215546Sopenharmony_ci DWORD Stencil ) 2106bf215546Sopenharmony_ci{ 2107bf215546Sopenharmony_ci struct NineSurface9 *zsbuf_surf = This->state.ds; 2108bf215546Sopenharmony_ci 2109bf215546Sopenharmony_ci DBG("This=%p Count=%u pRects=%p Flags=%x Color=%08x Z=%f Stencil=%x\n", 2110bf215546Sopenharmony_ci This, Count, pRects, Flags, Color, Z, Stencil); 2111bf215546Sopenharmony_ci 2112bf215546Sopenharmony_ci user_assert(This->state.ds || !(Flags & NINED3DCLEAR_DEPTHSTENCIL), 2113bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 2114bf215546Sopenharmony_ci user_assert(!(Flags & D3DCLEAR_STENCIL) || 2115bf215546Sopenharmony_ci (zsbuf_surf && 2116bf215546Sopenharmony_ci util_format_is_depth_and_stencil(zsbuf_surf->base.info.format)), 2117bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 2118bf215546Sopenharmony_ci#ifdef NINE_STRICT 2119bf215546Sopenharmony_ci user_assert((Count && pRects) || (!Count && !pRects), D3DERR_INVALIDCALL); 2120bf215546Sopenharmony_ci#else 2121bf215546Sopenharmony_ci user_warn((pRects && !Count) || (!pRects && Count)); 2122bf215546Sopenharmony_ci if (pRects && !Count) 2123bf215546Sopenharmony_ci return D3D_OK; 2124bf215546Sopenharmony_ci if (!pRects) 2125bf215546Sopenharmony_ci Count = 0; 2126bf215546Sopenharmony_ci#endif 2127bf215546Sopenharmony_ci 2128bf215546Sopenharmony_ci nine_context_clear_fb(This, Count, pRects, Flags, Color, Z, Stencil); 2129bf215546Sopenharmony_ci return D3D_OK; 2130bf215546Sopenharmony_ci} 2131bf215546Sopenharmony_ci 2132bf215546Sopenharmony_cistatic void 2133bf215546Sopenharmony_cinine_D3DMATRIX_print(const D3DMATRIX *M) 2134bf215546Sopenharmony_ci{ 2135bf215546Sopenharmony_ci DBG("\n(%f %f %f %f)\n" 2136bf215546Sopenharmony_ci "(%f %f %f %f)\n" 2137bf215546Sopenharmony_ci "(%f %f %f %f)\n" 2138bf215546Sopenharmony_ci "(%f %f %f %f)\n", 2139bf215546Sopenharmony_ci M->m[0][0], M->m[0][1], M->m[0][2], M->m[0][3], 2140bf215546Sopenharmony_ci M->m[1][0], M->m[1][1], M->m[1][2], M->m[1][3], 2141bf215546Sopenharmony_ci M->m[2][0], M->m[2][1], M->m[2][2], M->m[2][3], 2142bf215546Sopenharmony_ci M->m[3][0], M->m[3][1], M->m[3][2], M->m[3][3]); 2143bf215546Sopenharmony_ci} 2144bf215546Sopenharmony_ci 2145bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2146bf215546Sopenharmony_ciNineDevice9_SetTransform( struct NineDevice9 *This, 2147bf215546Sopenharmony_ci D3DTRANSFORMSTATETYPE State, 2148bf215546Sopenharmony_ci const D3DMATRIX *pMatrix ) 2149bf215546Sopenharmony_ci{ 2150bf215546Sopenharmony_ci struct nine_state *state = This->update; 2151bf215546Sopenharmony_ci D3DMATRIX *M = nine_state_access_transform(&state->ff, State, TRUE); 2152bf215546Sopenharmony_ci 2153bf215546Sopenharmony_ci DBG("This=%p State=%d pMatrix=%p\n", This, State, pMatrix); 2154bf215546Sopenharmony_ci 2155bf215546Sopenharmony_ci user_assert(pMatrix, D3DERR_INVALIDCALL); 2156bf215546Sopenharmony_ci user_assert(M, D3DERR_INVALIDCALL); 2157bf215546Sopenharmony_ci nine_D3DMATRIX_print(pMatrix); 2158bf215546Sopenharmony_ci 2159bf215546Sopenharmony_ci *M = *pMatrix; 2160bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 2161bf215546Sopenharmony_ci state->ff.changed.transform[State / 32] |= 1 << (State % 32); 2162bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_FF_VSTRANSF; 2163bf215546Sopenharmony_ci } else 2164bf215546Sopenharmony_ci nine_context_set_transform(This, State, pMatrix); 2165bf215546Sopenharmony_ci 2166bf215546Sopenharmony_ci return D3D_OK; 2167bf215546Sopenharmony_ci} 2168bf215546Sopenharmony_ci 2169bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2170bf215546Sopenharmony_ciNineDevice9_GetTransform( struct NineDevice9 *This, 2171bf215546Sopenharmony_ci D3DTRANSFORMSTATETYPE State, 2172bf215546Sopenharmony_ci D3DMATRIX *pMatrix ) 2173bf215546Sopenharmony_ci{ 2174bf215546Sopenharmony_ci D3DMATRIX *M; 2175bf215546Sopenharmony_ci 2176bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 2177bf215546Sopenharmony_ci M = nine_state_access_transform(&This->state.ff, State, FALSE); 2178bf215546Sopenharmony_ci user_assert(pMatrix, D3DERR_INVALIDCALL); 2179bf215546Sopenharmony_ci user_assert(M, D3DERR_INVALIDCALL); 2180bf215546Sopenharmony_ci *pMatrix = *M; 2181bf215546Sopenharmony_ci return D3D_OK; 2182bf215546Sopenharmony_ci} 2183bf215546Sopenharmony_ci 2184bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2185bf215546Sopenharmony_ciNineDevice9_MultiplyTransform( struct NineDevice9 *This, 2186bf215546Sopenharmony_ci D3DTRANSFORMSTATETYPE State, 2187bf215546Sopenharmony_ci const D3DMATRIX *pMatrix ) 2188bf215546Sopenharmony_ci{ 2189bf215546Sopenharmony_ci struct nine_state *state = This->update; 2190bf215546Sopenharmony_ci D3DMATRIX T; 2191bf215546Sopenharmony_ci D3DMATRIX *M = nine_state_access_transform(&state->ff, State, TRUE); 2192bf215546Sopenharmony_ci 2193bf215546Sopenharmony_ci DBG("This=%p State=%d pMatrix=%p\n", This, State, pMatrix); 2194bf215546Sopenharmony_ci 2195bf215546Sopenharmony_ci user_assert(pMatrix, D3DERR_INVALIDCALL); 2196bf215546Sopenharmony_ci user_assert(M, D3DERR_INVALIDCALL); 2197bf215546Sopenharmony_ci 2198bf215546Sopenharmony_ci nine_d3d_matrix_matrix_mul(&T, pMatrix, M); 2199bf215546Sopenharmony_ci return NineDevice9_SetTransform(This, State, &T); 2200bf215546Sopenharmony_ci} 2201bf215546Sopenharmony_ci 2202bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2203bf215546Sopenharmony_ciNineDevice9_SetViewport( struct NineDevice9 *This, 2204bf215546Sopenharmony_ci const D3DVIEWPORT9 *pViewport ) 2205bf215546Sopenharmony_ci{ 2206bf215546Sopenharmony_ci struct nine_state *state = This->update; 2207bf215546Sopenharmony_ci 2208bf215546Sopenharmony_ci DBG("X=%u Y=%u W=%u H=%u MinZ=%f MaxZ=%f\n", 2209bf215546Sopenharmony_ci pViewport->X, pViewport->Y, pViewport->Width, pViewport->Height, 2210bf215546Sopenharmony_ci pViewport->MinZ, pViewport->MaxZ); 2211bf215546Sopenharmony_ci 2212bf215546Sopenharmony_ci user_assert(pViewport != NULL, D3DERR_INVALIDCALL); 2213bf215546Sopenharmony_ci state->viewport = *pViewport; 2214bf215546Sopenharmony_ci nine_context_set_viewport(This, pViewport); 2215bf215546Sopenharmony_ci 2216bf215546Sopenharmony_ci return D3D_OK; 2217bf215546Sopenharmony_ci} 2218bf215546Sopenharmony_ci 2219bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2220bf215546Sopenharmony_ciNineDevice9_GetViewport( struct NineDevice9 *This, 2221bf215546Sopenharmony_ci D3DVIEWPORT9 *pViewport ) 2222bf215546Sopenharmony_ci{ 2223bf215546Sopenharmony_ci user_assert(pViewport != NULL, D3DERR_INVALIDCALL); 2224bf215546Sopenharmony_ci *pViewport = This->state.viewport; 2225bf215546Sopenharmony_ci return D3D_OK; 2226bf215546Sopenharmony_ci} 2227bf215546Sopenharmony_ci 2228bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2229bf215546Sopenharmony_ciNineDevice9_SetMaterial( struct NineDevice9 *This, 2230bf215546Sopenharmony_ci const D3DMATERIAL9 *pMaterial ) 2231bf215546Sopenharmony_ci{ 2232bf215546Sopenharmony_ci struct nine_state *state = This->update; 2233bf215546Sopenharmony_ci 2234bf215546Sopenharmony_ci DBG("This=%p pMaterial=%p\n", This, pMaterial); 2235bf215546Sopenharmony_ci if (pMaterial) 2236bf215546Sopenharmony_ci nine_dump_D3DMATERIAL9(DBG_FF, pMaterial); 2237bf215546Sopenharmony_ci 2238bf215546Sopenharmony_ci user_assert(pMaterial, E_POINTER); 2239bf215546Sopenharmony_ci 2240bf215546Sopenharmony_ci state->ff.material = *pMaterial; 2241bf215546Sopenharmony_ci if (unlikely(This->is_recording)) 2242bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_FF_MATERIAL; 2243bf215546Sopenharmony_ci else 2244bf215546Sopenharmony_ci nine_context_set_material(This, pMaterial); 2245bf215546Sopenharmony_ci 2246bf215546Sopenharmony_ci return D3D_OK; 2247bf215546Sopenharmony_ci} 2248bf215546Sopenharmony_ci 2249bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2250bf215546Sopenharmony_ciNineDevice9_GetMaterial( struct NineDevice9 *This, 2251bf215546Sopenharmony_ci D3DMATERIAL9 *pMaterial ) 2252bf215546Sopenharmony_ci{ 2253bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 2254bf215546Sopenharmony_ci user_assert(pMaterial, E_POINTER); 2255bf215546Sopenharmony_ci *pMaterial = This->state.ff.material; 2256bf215546Sopenharmony_ci return D3D_OK; 2257bf215546Sopenharmony_ci} 2258bf215546Sopenharmony_ci 2259bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2260bf215546Sopenharmony_ciNineDevice9_SetLight( struct NineDevice9 *This, 2261bf215546Sopenharmony_ci DWORD Index, 2262bf215546Sopenharmony_ci const D3DLIGHT9 *pLight ) 2263bf215546Sopenharmony_ci{ 2264bf215546Sopenharmony_ci struct nine_state *state = This->update; 2265bf215546Sopenharmony_ci HRESULT hr; 2266bf215546Sopenharmony_ci 2267bf215546Sopenharmony_ci DBG("This=%p Index=%u pLight=%p\n", This, Index, pLight); 2268bf215546Sopenharmony_ci if (pLight) 2269bf215546Sopenharmony_ci nine_dump_D3DLIGHT9(DBG_FF, pLight); 2270bf215546Sopenharmony_ci 2271bf215546Sopenharmony_ci user_assert(pLight, D3DERR_INVALIDCALL); 2272bf215546Sopenharmony_ci user_assert(pLight->Type < NINED3DLIGHT_INVALID, D3DERR_INVALIDCALL); 2273bf215546Sopenharmony_ci 2274bf215546Sopenharmony_ci user_assert(Index < NINE_MAX_LIGHTS, D3DERR_INVALIDCALL); /* sanity */ 2275bf215546Sopenharmony_ci 2276bf215546Sopenharmony_ci hr = nine_state_set_light(&state->ff, Index, pLight); 2277bf215546Sopenharmony_ci if (hr != D3D_OK) 2278bf215546Sopenharmony_ci return hr; 2279bf215546Sopenharmony_ci 2280bf215546Sopenharmony_ci if (pLight->Type != D3DLIGHT_DIRECTIONAL && 2281bf215546Sopenharmony_ci pLight->Attenuation0 == 0.0f && 2282bf215546Sopenharmony_ci pLight->Attenuation1 == 0.0f && 2283bf215546Sopenharmony_ci pLight->Attenuation2 == 0.0f) { 2284bf215546Sopenharmony_ci DBG("Warning: all D3DLIGHT9.Attenuation[i] are 0\n"); 2285bf215546Sopenharmony_ci } 2286bf215546Sopenharmony_ci 2287bf215546Sopenharmony_ci if (unlikely(This->is_recording)) 2288bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_FF_LIGHTING; 2289bf215546Sopenharmony_ci else 2290bf215546Sopenharmony_ci nine_context_set_light(This, Index, pLight); 2291bf215546Sopenharmony_ci 2292bf215546Sopenharmony_ci return D3D_OK; 2293bf215546Sopenharmony_ci} 2294bf215546Sopenharmony_ci 2295bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2296bf215546Sopenharmony_ciNineDevice9_GetLight( struct NineDevice9 *This, 2297bf215546Sopenharmony_ci DWORD Index, 2298bf215546Sopenharmony_ci D3DLIGHT9 *pLight ) 2299bf215546Sopenharmony_ci{ 2300bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 2301bf215546Sopenharmony_ci 2302bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 2303bf215546Sopenharmony_ci user_assert(pLight, D3DERR_INVALIDCALL); 2304bf215546Sopenharmony_ci user_assert(Index < state->ff.num_lights, D3DERR_INVALIDCALL); 2305bf215546Sopenharmony_ci user_assert(state->ff.light[Index].Type < NINED3DLIGHT_INVALID, 2306bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 2307bf215546Sopenharmony_ci 2308bf215546Sopenharmony_ci *pLight = state->ff.light[Index]; 2309bf215546Sopenharmony_ci 2310bf215546Sopenharmony_ci return D3D_OK; 2311bf215546Sopenharmony_ci} 2312bf215546Sopenharmony_ci 2313bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2314bf215546Sopenharmony_ciNineDevice9_LightEnable( struct NineDevice9 *This, 2315bf215546Sopenharmony_ci DWORD Index, 2316bf215546Sopenharmony_ci BOOL Enable ) 2317bf215546Sopenharmony_ci{ 2318bf215546Sopenharmony_ci struct nine_state *state = This->update; 2319bf215546Sopenharmony_ci 2320bf215546Sopenharmony_ci DBG("This=%p Index=%u Enable=%i\n", This, Index, Enable); 2321bf215546Sopenharmony_ci 2322bf215546Sopenharmony_ci if (Index >= state->ff.num_lights || 2323bf215546Sopenharmony_ci state->ff.light[Index].Type == NINED3DLIGHT_INVALID) { 2324bf215546Sopenharmony_ci /* This should create a default light. */ 2325bf215546Sopenharmony_ci D3DLIGHT9 light; 2326bf215546Sopenharmony_ci memset(&light, 0, sizeof(light)); 2327bf215546Sopenharmony_ci light.Type = D3DLIGHT_DIRECTIONAL; 2328bf215546Sopenharmony_ci light.Diffuse.r = 1.0f; 2329bf215546Sopenharmony_ci light.Diffuse.g = 1.0f; 2330bf215546Sopenharmony_ci light.Diffuse.b = 1.0f; 2331bf215546Sopenharmony_ci light.Direction.z = 1.0f; 2332bf215546Sopenharmony_ci NineDevice9_SetLight(This, Index, &light); 2333bf215546Sopenharmony_ci } 2334bf215546Sopenharmony_ci 2335bf215546Sopenharmony_ci nine_state_light_enable(&state->ff, Index, Enable); 2336bf215546Sopenharmony_ci if (likely(!This->is_recording)) 2337bf215546Sopenharmony_ci nine_context_light_enable(This, Index, Enable); 2338bf215546Sopenharmony_ci else 2339bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_FF_LIGHTING; 2340bf215546Sopenharmony_ci 2341bf215546Sopenharmony_ci return D3D_OK; 2342bf215546Sopenharmony_ci} 2343bf215546Sopenharmony_ci 2344bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2345bf215546Sopenharmony_ciNineDevice9_GetLightEnable( struct NineDevice9 *This, 2346bf215546Sopenharmony_ci DWORD Index, 2347bf215546Sopenharmony_ci BOOL *pEnable ) 2348bf215546Sopenharmony_ci{ 2349bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 2350bf215546Sopenharmony_ci unsigned i; 2351bf215546Sopenharmony_ci 2352bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 2353bf215546Sopenharmony_ci user_assert(pEnable != NULL, D3DERR_INVALIDCALL); 2354bf215546Sopenharmony_ci user_assert(Index < state->ff.num_lights, D3DERR_INVALIDCALL); 2355bf215546Sopenharmony_ci user_assert(state->ff.light[Index].Type < NINED3DLIGHT_INVALID, 2356bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 2357bf215546Sopenharmony_ci 2358bf215546Sopenharmony_ci for (i = 0; i < state->ff.num_lights_active; ++i) 2359bf215546Sopenharmony_ci if (state->ff.active_light[i] == Index) 2360bf215546Sopenharmony_ci break; 2361bf215546Sopenharmony_ci 2362bf215546Sopenharmony_ci *pEnable = i != state->ff.num_lights_active ? 128 : 0; // Taken from wine 2363bf215546Sopenharmony_ci 2364bf215546Sopenharmony_ci return D3D_OK; 2365bf215546Sopenharmony_ci} 2366bf215546Sopenharmony_ci 2367bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2368bf215546Sopenharmony_ciNineDevice9_SetClipPlane( struct NineDevice9 *This, 2369bf215546Sopenharmony_ci DWORD Index, 2370bf215546Sopenharmony_ci const float *pPlane ) 2371bf215546Sopenharmony_ci{ 2372bf215546Sopenharmony_ci struct nine_state *state = This->update; 2373bf215546Sopenharmony_ci 2374bf215546Sopenharmony_ci user_assert(pPlane, D3DERR_INVALIDCALL); 2375bf215546Sopenharmony_ci 2376bf215546Sopenharmony_ci DBG("This=%p Index=%u pPlane=%f %f %f %f\n", This, Index, 2377bf215546Sopenharmony_ci pPlane[0], pPlane[1], 2378bf215546Sopenharmony_ci pPlane[2], pPlane[3]); 2379bf215546Sopenharmony_ci 2380bf215546Sopenharmony_ci user_assert(Index < PIPE_MAX_CLIP_PLANES, D3DERR_INVALIDCALL); 2381bf215546Sopenharmony_ci 2382bf215546Sopenharmony_ci memcpy(&state->clip.ucp[Index][0], pPlane, sizeof(state->clip.ucp[0])); 2383bf215546Sopenharmony_ci if (unlikely(This->is_recording)) 2384bf215546Sopenharmony_ci state->changed.ucp |= 1 << Index; 2385bf215546Sopenharmony_ci else 2386bf215546Sopenharmony_ci nine_context_set_clip_plane(This, Index, (struct nine_clipplane *)pPlane); 2387bf215546Sopenharmony_ci 2388bf215546Sopenharmony_ci return D3D_OK; 2389bf215546Sopenharmony_ci} 2390bf215546Sopenharmony_ci 2391bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2392bf215546Sopenharmony_ciNineDevice9_GetClipPlane( struct NineDevice9 *This, 2393bf215546Sopenharmony_ci DWORD Index, 2394bf215546Sopenharmony_ci float *pPlane ) 2395bf215546Sopenharmony_ci{ 2396bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 2397bf215546Sopenharmony_ci 2398bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 2399bf215546Sopenharmony_ci user_assert(pPlane != NULL, D3DERR_INVALIDCALL); 2400bf215546Sopenharmony_ci user_assert(Index < PIPE_MAX_CLIP_PLANES, D3DERR_INVALIDCALL); 2401bf215546Sopenharmony_ci 2402bf215546Sopenharmony_ci memcpy(pPlane, &state->clip.ucp[Index][0], sizeof(state->clip.ucp[0])); 2403bf215546Sopenharmony_ci return D3D_OK; 2404bf215546Sopenharmony_ci} 2405bf215546Sopenharmony_ci 2406bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2407bf215546Sopenharmony_ciNineDevice9_SetRenderState( struct NineDevice9 *This, 2408bf215546Sopenharmony_ci D3DRENDERSTATETYPE State, 2409bf215546Sopenharmony_ci DWORD Value ) 2410bf215546Sopenharmony_ci{ 2411bf215546Sopenharmony_ci struct nine_state *state = This->update; 2412bf215546Sopenharmony_ci 2413bf215546Sopenharmony_ci DBG("This=%p State=%u(%s) Value=%08x\n", This, 2414bf215546Sopenharmony_ci State, nine_d3drs_to_string(State), Value); 2415bf215546Sopenharmony_ci 2416bf215546Sopenharmony_ci user_assert(State < D3DRS_COUNT, D3D_OK); 2417bf215546Sopenharmony_ci 2418bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 2419bf215546Sopenharmony_ci state->rs_advertised[State] = Value; 2420bf215546Sopenharmony_ci /* only need to record changed render states for stateblocks */ 2421bf215546Sopenharmony_ci state->changed.rs[State / 32] |= 1 << (State % 32); 2422bf215546Sopenharmony_ci return D3D_OK; 2423bf215546Sopenharmony_ci } 2424bf215546Sopenharmony_ci 2425bf215546Sopenharmony_ci if (state->rs_advertised[State] == Value) 2426bf215546Sopenharmony_ci return D3D_OK; 2427bf215546Sopenharmony_ci 2428bf215546Sopenharmony_ci state->rs_advertised[State] = Value; 2429bf215546Sopenharmony_ci nine_context_set_render_state(This, State, Value); 2430bf215546Sopenharmony_ci 2431bf215546Sopenharmony_ci return D3D_OK; 2432bf215546Sopenharmony_ci} 2433bf215546Sopenharmony_ci 2434bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2435bf215546Sopenharmony_ciNineDevice9_GetRenderState( struct NineDevice9 *This, 2436bf215546Sopenharmony_ci D3DRENDERSTATETYPE State, 2437bf215546Sopenharmony_ci DWORD *pValue ) 2438bf215546Sopenharmony_ci{ 2439bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 2440bf215546Sopenharmony_ci user_assert(pValue != NULL, D3DERR_INVALIDCALL); 2441bf215546Sopenharmony_ci /* TODO: This needs tests */ 2442bf215546Sopenharmony_ci if (State >= D3DRS_COUNT) { 2443bf215546Sopenharmony_ci *pValue = 0; 2444bf215546Sopenharmony_ci return D3D_OK; 2445bf215546Sopenharmony_ci } 2446bf215546Sopenharmony_ci 2447bf215546Sopenharmony_ci *pValue = This->state.rs_advertised[State]; 2448bf215546Sopenharmony_ci return D3D_OK; 2449bf215546Sopenharmony_ci} 2450bf215546Sopenharmony_ci 2451bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2452bf215546Sopenharmony_ciNineDevice9_CreateStateBlock( struct NineDevice9 *This, 2453bf215546Sopenharmony_ci D3DSTATEBLOCKTYPE Type, 2454bf215546Sopenharmony_ci IDirect3DStateBlock9 **ppSB ) 2455bf215546Sopenharmony_ci{ 2456bf215546Sopenharmony_ci struct NineStateBlock9 *nsb; 2457bf215546Sopenharmony_ci struct nine_state *dst; 2458bf215546Sopenharmony_ci HRESULT hr; 2459bf215546Sopenharmony_ci enum nine_stateblock_type type; 2460bf215546Sopenharmony_ci unsigned s; 2461bf215546Sopenharmony_ci 2462bf215546Sopenharmony_ci DBG("This=%p Type=%u ppSB=%p\n", This, Type, ppSB); 2463bf215546Sopenharmony_ci 2464bf215546Sopenharmony_ci user_assert(ppSB != NULL, D3DERR_INVALIDCALL); 2465bf215546Sopenharmony_ci user_assert(Type == D3DSBT_ALL || 2466bf215546Sopenharmony_ci Type == D3DSBT_VERTEXSTATE || 2467bf215546Sopenharmony_ci Type == D3DSBT_PIXELSTATE, D3DERR_INVALIDCALL); 2468bf215546Sopenharmony_ci 2469bf215546Sopenharmony_ci switch (Type) { 2470bf215546Sopenharmony_ci case D3DSBT_VERTEXSTATE: type = NINESBT_VERTEXSTATE; break; 2471bf215546Sopenharmony_ci case D3DSBT_PIXELSTATE: type = NINESBT_PIXELSTATE; break; 2472bf215546Sopenharmony_ci default: 2473bf215546Sopenharmony_ci type = NINESBT_ALL; 2474bf215546Sopenharmony_ci break; 2475bf215546Sopenharmony_ci } 2476bf215546Sopenharmony_ci 2477bf215546Sopenharmony_ci hr = NineStateBlock9_new(This, &nsb, type); 2478bf215546Sopenharmony_ci if (FAILED(hr)) 2479bf215546Sopenharmony_ci return hr; 2480bf215546Sopenharmony_ci *ppSB = (IDirect3DStateBlock9 *)nsb; 2481bf215546Sopenharmony_ci dst = &nsb->state; 2482bf215546Sopenharmony_ci 2483bf215546Sopenharmony_ci dst->changed.group = NINE_STATE_SAMPLER; 2484bf215546Sopenharmony_ci 2485bf215546Sopenharmony_ci if (Type == D3DSBT_ALL || Type == D3DSBT_VERTEXSTATE) { 2486bf215546Sopenharmony_ci dst->changed.group |= 2487bf215546Sopenharmony_ci NINE_STATE_FF_LIGHTING | 2488bf215546Sopenharmony_ci NINE_STATE_VS | NINE_STATE_VS_CONST | 2489bf215546Sopenharmony_ci NINE_STATE_VDECL; 2490bf215546Sopenharmony_ci /* TODO: texture/sampler state */ 2491bf215546Sopenharmony_ci memcpy(dst->changed.rs, 2492bf215546Sopenharmony_ci nine_render_states_vertex, sizeof(dst->changed.rs)); 2493bf215546Sopenharmony_ci nine_ranges_insert(&dst->changed.vs_const_f, 0, This->may_swvp ? NINE_MAX_CONST_F_SWVP : This->max_vs_const_f, 2494bf215546Sopenharmony_ci &This->range_pool); 2495bf215546Sopenharmony_ci nine_ranges_insert(&dst->changed.vs_const_i, 0, This->may_swvp ? NINE_MAX_CONST_I_SWVP : NINE_MAX_CONST_I, 2496bf215546Sopenharmony_ci &This->range_pool); 2497bf215546Sopenharmony_ci nine_ranges_insert(&dst->changed.vs_const_b, 0, This->may_swvp ? NINE_MAX_CONST_B_SWVP : NINE_MAX_CONST_B, 2498bf215546Sopenharmony_ci &This->range_pool); 2499bf215546Sopenharmony_ci for (s = 0; s < NINE_MAX_SAMPLERS; ++s) 2500bf215546Sopenharmony_ci dst->changed.sampler[s] |= 1 << D3DSAMP_DMAPOFFSET; 2501bf215546Sopenharmony_ci if (This->state.ff.num_lights) { 2502bf215546Sopenharmony_ci dst->ff.num_lights = This->state.ff.num_lights; 2503bf215546Sopenharmony_ci /* zero'd -> light type won't be NINED3DLIGHT_INVALID, so 2504bf215546Sopenharmony_ci * all currently existing lights will be captured 2505bf215546Sopenharmony_ci */ 2506bf215546Sopenharmony_ci dst->ff.light = CALLOC(This->state.ff.num_lights, 2507bf215546Sopenharmony_ci sizeof(D3DLIGHT9)); 2508bf215546Sopenharmony_ci if (!dst->ff.light) { 2509bf215546Sopenharmony_ci nine_bind(ppSB, NULL); 2510bf215546Sopenharmony_ci return E_OUTOFMEMORY; 2511bf215546Sopenharmony_ci } 2512bf215546Sopenharmony_ci } 2513bf215546Sopenharmony_ci } 2514bf215546Sopenharmony_ci if (Type == D3DSBT_ALL || Type == D3DSBT_PIXELSTATE) { 2515bf215546Sopenharmony_ci dst->changed.group |= 2516bf215546Sopenharmony_ci NINE_STATE_PS | NINE_STATE_PS_CONST | NINE_STATE_FF_PS_CONSTS; 2517bf215546Sopenharmony_ci memcpy(dst->changed.rs, 2518bf215546Sopenharmony_ci nine_render_states_pixel, sizeof(dst->changed.rs)); 2519bf215546Sopenharmony_ci nine_ranges_insert(&dst->changed.ps_const_f, 0, This->max_ps_const_f, 2520bf215546Sopenharmony_ci &This->range_pool); 2521bf215546Sopenharmony_ci dst->changed.ps_const_i = 0xffff; 2522bf215546Sopenharmony_ci dst->changed.ps_const_b = 0xffff; 2523bf215546Sopenharmony_ci for (s = 0; s < NINE_MAX_SAMPLERS; ++s) 2524bf215546Sopenharmony_ci dst->changed.sampler[s] |= 0x1ffe; 2525bf215546Sopenharmony_ci for (s = 0; s < NINE_MAX_TEXTURE_STAGES; ++s) { 2526bf215546Sopenharmony_ci dst->ff.changed.tex_stage[s][0] |= 0xffffffff; 2527bf215546Sopenharmony_ci dst->ff.changed.tex_stage[s][1] |= 0xffffffff; 2528bf215546Sopenharmony_ci } 2529bf215546Sopenharmony_ci } 2530bf215546Sopenharmony_ci if (Type == D3DSBT_ALL) { 2531bf215546Sopenharmony_ci dst->changed.group |= 2532bf215546Sopenharmony_ci NINE_STATE_VIEWPORT | 2533bf215546Sopenharmony_ci NINE_STATE_SCISSOR | 2534bf215546Sopenharmony_ci NINE_STATE_IDXBUF | 2535bf215546Sopenharmony_ci NINE_STATE_FF_MATERIAL | 2536bf215546Sopenharmony_ci NINE_STATE_FF_VSTRANSF; 2537bf215546Sopenharmony_ci memset(dst->changed.rs, ~0, (D3DRS_COUNT / 32) * sizeof(uint32_t)); 2538bf215546Sopenharmony_ci dst->changed.rs[D3DRS_LAST / 32] |= (1 << (D3DRS_COUNT % 32)) - 1; 2539bf215546Sopenharmony_ci dst->changed.vtxbuf = (1ULL << This->caps.MaxStreams) - 1; 2540bf215546Sopenharmony_ci dst->changed.stream_freq = dst->changed.vtxbuf; 2541bf215546Sopenharmony_ci dst->changed.ucp = (1 << PIPE_MAX_CLIP_PLANES) - 1; 2542bf215546Sopenharmony_ci dst->changed.texture = (1 << NINE_MAX_SAMPLERS) - 1; 2543bf215546Sopenharmony_ci /* The doc says the projection, world, view and texture matrices 2544bf215546Sopenharmony_ci * are saved, which would translate to: 2545bf215546Sopenharmony_ci * dst->ff.changed.transform[0] = 0x00FF000C; 2546bf215546Sopenharmony_ci * dst->ff.changed.transform[D3DTS_WORLD / 32] |= 1 << (D3DTS_WORLD % 32); 2547bf215546Sopenharmony_ci * However we assume they meant save everything (which is basically just the 2548bf215546Sopenharmony_ci * above plus the other world matrices). 2549bf215546Sopenharmony_ci */ 2550bf215546Sopenharmony_ci dst->ff.changed.transform[0] = 0x00FF000C; 2551bf215546Sopenharmony_ci for (s = 0; s < 8; s++) 2552bf215546Sopenharmony_ci dst->ff.changed.transform[8+s] = ~0; 2553bf215546Sopenharmony_ci } 2554bf215546Sopenharmony_ci NineStateBlock9_Capture(NineStateBlock9(*ppSB)); 2555bf215546Sopenharmony_ci 2556bf215546Sopenharmony_ci /* TODO: fixed function state */ 2557bf215546Sopenharmony_ci 2558bf215546Sopenharmony_ci return D3D_OK; 2559bf215546Sopenharmony_ci} 2560bf215546Sopenharmony_ci 2561bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2562bf215546Sopenharmony_ciNineDevice9_BeginStateBlock( struct NineDevice9 *This ) 2563bf215546Sopenharmony_ci{ 2564bf215546Sopenharmony_ci HRESULT hr; 2565bf215546Sopenharmony_ci 2566bf215546Sopenharmony_ci DBG("This=%p\n", This); 2567bf215546Sopenharmony_ci 2568bf215546Sopenharmony_ci user_assert(!This->record, D3DERR_INVALIDCALL); 2569bf215546Sopenharmony_ci 2570bf215546Sopenharmony_ci hr = NineStateBlock9_new(This, &This->record, NINESBT_CUSTOM); 2571bf215546Sopenharmony_ci if (FAILED(hr)) 2572bf215546Sopenharmony_ci return hr; 2573bf215546Sopenharmony_ci NineUnknown_ConvertRefToBind(NineUnknown(This->record)); 2574bf215546Sopenharmony_ci 2575bf215546Sopenharmony_ci This->update = &This->record->state; 2576bf215546Sopenharmony_ci This->is_recording = TRUE; 2577bf215546Sopenharmony_ci 2578bf215546Sopenharmony_ci return D3D_OK; 2579bf215546Sopenharmony_ci} 2580bf215546Sopenharmony_ci 2581bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2582bf215546Sopenharmony_ciNineDevice9_EndStateBlock( struct NineDevice9 *This, 2583bf215546Sopenharmony_ci IDirect3DStateBlock9 **ppSB ) 2584bf215546Sopenharmony_ci{ 2585bf215546Sopenharmony_ci DBG("This=%p ppSB=%p\n", This, ppSB); 2586bf215546Sopenharmony_ci 2587bf215546Sopenharmony_ci user_assert(This->record, D3DERR_INVALIDCALL); 2588bf215546Sopenharmony_ci user_assert(ppSB != NULL, D3DERR_INVALIDCALL); 2589bf215546Sopenharmony_ci 2590bf215546Sopenharmony_ci This->update = &This->state; 2591bf215546Sopenharmony_ci This->is_recording = FALSE; 2592bf215546Sopenharmony_ci 2593bf215546Sopenharmony_ci NineUnknown_AddRef(NineUnknown(This->record)); 2594bf215546Sopenharmony_ci *ppSB = (IDirect3DStateBlock9 *)This->record; 2595bf215546Sopenharmony_ci NineUnknown_Unbind(NineUnknown(This->record)); 2596bf215546Sopenharmony_ci This->record = NULL; 2597bf215546Sopenharmony_ci 2598bf215546Sopenharmony_ci return D3D_OK; 2599bf215546Sopenharmony_ci} 2600bf215546Sopenharmony_ci 2601bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2602bf215546Sopenharmony_ciNineDevice9_SetClipStatus( struct NineDevice9 *This, 2603bf215546Sopenharmony_ci const D3DCLIPSTATUS9 *pClipStatus ) 2604bf215546Sopenharmony_ci{ 2605bf215546Sopenharmony_ci user_assert(pClipStatus, D3DERR_INVALIDCALL); 2606bf215546Sopenharmony_ci return D3D_OK; 2607bf215546Sopenharmony_ci} 2608bf215546Sopenharmony_ci 2609bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2610bf215546Sopenharmony_ciNineDevice9_GetClipStatus( struct NineDevice9 *This, 2611bf215546Sopenharmony_ci D3DCLIPSTATUS9 *pClipStatus ) 2612bf215546Sopenharmony_ci{ 2613bf215546Sopenharmony_ci user_assert(pClipStatus, D3DERR_INVALIDCALL); 2614bf215546Sopenharmony_ci /* Set/GetClipStatus is supposed to get the app some infos 2615bf215546Sopenharmony_ci * about vertices being clipped if it is using the software 2616bf215546Sopenharmony_ci * vertex rendering. It would be too complicated to implement. 2617bf215546Sopenharmony_ci * Probably the info is for developpers when working on their 2618bf215546Sopenharmony_ci * applications. Else it could be for apps to know if it is worth 2619bf215546Sopenharmony_ci * drawing some elements. In that case it makes sense to send 2620bf215546Sopenharmony_ci * 0 for ClipUnion and 0xFFFFFFFF for ClipIntersection (basically 2621bf215546Sopenharmony_ci * means not all vertices are clipped). Those values are known to 2622bf215546Sopenharmony_ci * be the default if SetClipStatus is not set. Else we could return 2623bf215546Sopenharmony_ci * what was set with SetClipStatus unchanged. */ 2624bf215546Sopenharmony_ci pClipStatus->ClipUnion = 0; 2625bf215546Sopenharmony_ci pClipStatus->ClipIntersection = 0xFFFFFFFF; 2626bf215546Sopenharmony_ci return D3D_OK; 2627bf215546Sopenharmony_ci} 2628bf215546Sopenharmony_ci 2629bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2630bf215546Sopenharmony_ciNineDevice9_GetTexture( struct NineDevice9 *This, 2631bf215546Sopenharmony_ci DWORD Stage, 2632bf215546Sopenharmony_ci IDirect3DBaseTexture9 **ppTexture ) 2633bf215546Sopenharmony_ci{ 2634bf215546Sopenharmony_ci user_assert(Stage < NINE_MAX_SAMPLERS_PS || 2635bf215546Sopenharmony_ci Stage == D3DDMAPSAMPLER || 2636bf215546Sopenharmony_ci (Stage >= D3DVERTEXTEXTURESAMPLER0 && 2637bf215546Sopenharmony_ci Stage <= D3DVERTEXTEXTURESAMPLER3), D3DERR_INVALIDCALL); 2638bf215546Sopenharmony_ci user_assert(ppTexture, D3DERR_INVALIDCALL); 2639bf215546Sopenharmony_ci 2640bf215546Sopenharmony_ci if (Stage >= D3DDMAPSAMPLER) 2641bf215546Sopenharmony_ci Stage = Stage - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS; 2642bf215546Sopenharmony_ci 2643bf215546Sopenharmony_ci *ppTexture = (IDirect3DBaseTexture9 *)This->state.texture[Stage]; 2644bf215546Sopenharmony_ci 2645bf215546Sopenharmony_ci if (This->state.texture[Stage]) 2646bf215546Sopenharmony_ci NineUnknown_AddRef(NineUnknown(This->state.texture[Stage])); 2647bf215546Sopenharmony_ci return D3D_OK; 2648bf215546Sopenharmony_ci} 2649bf215546Sopenharmony_ci 2650bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2651bf215546Sopenharmony_ciNineDevice9_SetTexture( struct NineDevice9 *This, 2652bf215546Sopenharmony_ci DWORD Stage, 2653bf215546Sopenharmony_ci IDirect3DBaseTexture9 *pTexture ) 2654bf215546Sopenharmony_ci{ 2655bf215546Sopenharmony_ci struct nine_state *state = This->update; 2656bf215546Sopenharmony_ci struct NineBaseTexture9 *tex = NineBaseTexture9(pTexture); 2657bf215546Sopenharmony_ci struct NineBaseTexture9 *old; 2658bf215546Sopenharmony_ci 2659bf215546Sopenharmony_ci DBG("This=%p Stage=%u pTexture=%p\n", This, Stage, pTexture); 2660bf215546Sopenharmony_ci 2661bf215546Sopenharmony_ci user_assert(Stage < NINE_MAX_SAMPLERS_PS || 2662bf215546Sopenharmony_ci Stage == D3DDMAPSAMPLER || 2663bf215546Sopenharmony_ci (Stage >= D3DVERTEXTEXTURESAMPLER0 && 2664bf215546Sopenharmony_ci Stage <= D3DVERTEXTEXTURESAMPLER3), D3DERR_INVALIDCALL); 2665bf215546Sopenharmony_ci user_assert(!tex || (tex->base.pool != D3DPOOL_SCRATCH && 2666bf215546Sopenharmony_ci tex->base.pool != D3DPOOL_SYSTEMMEM), D3DERR_INVALIDCALL); 2667bf215546Sopenharmony_ci 2668bf215546Sopenharmony_ci if (Stage >= D3DDMAPSAMPLER) 2669bf215546Sopenharmony_ci Stage = Stage - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS; 2670bf215546Sopenharmony_ci 2671bf215546Sopenharmony_ci if (This->is_recording) { 2672bf215546Sopenharmony_ci state->changed.texture |= 1 << Stage; 2673bf215546Sopenharmony_ci nine_bind(&state->texture[Stage], pTexture); 2674bf215546Sopenharmony_ci return D3D_OK; 2675bf215546Sopenharmony_ci } 2676bf215546Sopenharmony_ci 2677bf215546Sopenharmony_ci old = state->texture[Stage]; 2678bf215546Sopenharmony_ci if (old == tex) 2679bf215546Sopenharmony_ci return D3D_OK; 2680bf215546Sopenharmony_ci 2681bf215546Sopenharmony_ci NineBindTextureToDevice(This, &state->texture[Stage], tex); 2682bf215546Sopenharmony_ci 2683bf215546Sopenharmony_ci nine_context_set_texture(This, Stage, tex); 2684bf215546Sopenharmony_ci 2685bf215546Sopenharmony_ci return D3D_OK; 2686bf215546Sopenharmony_ci} 2687bf215546Sopenharmony_ci 2688bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2689bf215546Sopenharmony_ciNineDevice9_GetTextureStageState( struct NineDevice9 *This, 2690bf215546Sopenharmony_ci DWORD Stage, 2691bf215546Sopenharmony_ci D3DTEXTURESTAGESTATETYPE Type, 2692bf215546Sopenharmony_ci DWORD *pValue ) 2693bf215546Sopenharmony_ci{ 2694bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 2695bf215546Sopenharmony_ci 2696bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 2697bf215546Sopenharmony_ci user_assert(pValue != NULL, D3DERR_INVALIDCALL); 2698bf215546Sopenharmony_ci user_assert(Stage < ARRAY_SIZE(state->ff.tex_stage), D3DERR_INVALIDCALL); 2699bf215546Sopenharmony_ci user_assert(Type < ARRAY_SIZE(state->ff.tex_stage[0]), D3DERR_INVALIDCALL); 2700bf215546Sopenharmony_ci 2701bf215546Sopenharmony_ci *pValue = state->ff.tex_stage[Stage][Type]; 2702bf215546Sopenharmony_ci 2703bf215546Sopenharmony_ci return D3D_OK; 2704bf215546Sopenharmony_ci} 2705bf215546Sopenharmony_ci 2706bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2707bf215546Sopenharmony_ciNineDevice9_SetTextureStageState( struct NineDevice9 *This, 2708bf215546Sopenharmony_ci DWORD Stage, 2709bf215546Sopenharmony_ci D3DTEXTURESTAGESTATETYPE Type, 2710bf215546Sopenharmony_ci DWORD Value ) 2711bf215546Sopenharmony_ci{ 2712bf215546Sopenharmony_ci struct nine_state *state = This->update; 2713bf215546Sopenharmony_ci 2714bf215546Sopenharmony_ci DBG("Stage=%u Type=%u Value=%08x\n", Stage, Type, Value); 2715bf215546Sopenharmony_ci nine_dump_D3DTSS_value(DBG_FF, Type, Value); 2716bf215546Sopenharmony_ci 2717bf215546Sopenharmony_ci user_assert(Stage < ARRAY_SIZE(state->ff.tex_stage), D3DERR_INVALIDCALL); 2718bf215546Sopenharmony_ci user_assert(Type < ARRAY_SIZE(state->ff.tex_stage[0]), D3DERR_INVALIDCALL); 2719bf215546Sopenharmony_ci 2720bf215546Sopenharmony_ci state->ff.tex_stage[Stage][Type] = Value; 2721bf215546Sopenharmony_ci 2722bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 2723bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_FF_PS_CONSTS; 2724bf215546Sopenharmony_ci state->ff.changed.tex_stage[Stage][Type / 32] |= 1 << (Type % 32); 2725bf215546Sopenharmony_ci } else 2726bf215546Sopenharmony_ci nine_context_set_texture_stage_state(This, Stage, Type, Value); 2727bf215546Sopenharmony_ci 2728bf215546Sopenharmony_ci return D3D_OK; 2729bf215546Sopenharmony_ci} 2730bf215546Sopenharmony_ci 2731bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2732bf215546Sopenharmony_ciNineDevice9_GetSamplerState( struct NineDevice9 *This, 2733bf215546Sopenharmony_ci DWORD Sampler, 2734bf215546Sopenharmony_ci D3DSAMPLERSTATETYPE Type, 2735bf215546Sopenharmony_ci DWORD *pValue ) 2736bf215546Sopenharmony_ci{ 2737bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 2738bf215546Sopenharmony_ci user_assert(pValue != NULL, D3DERR_INVALIDCALL); 2739bf215546Sopenharmony_ci user_assert(Sampler < NINE_MAX_SAMPLERS_PS || 2740bf215546Sopenharmony_ci Sampler == D3DDMAPSAMPLER || 2741bf215546Sopenharmony_ci (Sampler >= D3DVERTEXTEXTURESAMPLER0 && 2742bf215546Sopenharmony_ci Sampler <= D3DVERTEXTEXTURESAMPLER3), D3DERR_INVALIDCALL); 2743bf215546Sopenharmony_ci 2744bf215546Sopenharmony_ci if (Sampler >= D3DDMAPSAMPLER) 2745bf215546Sopenharmony_ci Sampler = Sampler - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS; 2746bf215546Sopenharmony_ci 2747bf215546Sopenharmony_ci *pValue = This->state.samp_advertised[Sampler][Type]; 2748bf215546Sopenharmony_ci return D3D_OK; 2749bf215546Sopenharmony_ci} 2750bf215546Sopenharmony_ci 2751bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2752bf215546Sopenharmony_ciNineDevice9_SetSamplerState( struct NineDevice9 *This, 2753bf215546Sopenharmony_ci DWORD Sampler, 2754bf215546Sopenharmony_ci D3DSAMPLERSTATETYPE Type, 2755bf215546Sopenharmony_ci DWORD Value ) 2756bf215546Sopenharmony_ci{ 2757bf215546Sopenharmony_ci struct nine_state *state = This->update; 2758bf215546Sopenharmony_ci 2759bf215546Sopenharmony_ci DBG("This=%p Sampler=%u Type=%s Value=%08x\n", This, 2760bf215546Sopenharmony_ci Sampler, nine_D3DSAMP_to_str(Type), Value); 2761bf215546Sopenharmony_ci 2762bf215546Sopenharmony_ci user_assert(Sampler < NINE_MAX_SAMPLERS_PS || 2763bf215546Sopenharmony_ci Sampler == D3DDMAPSAMPLER || 2764bf215546Sopenharmony_ci (Sampler >= D3DVERTEXTEXTURESAMPLER0 && 2765bf215546Sopenharmony_ci Sampler <= D3DVERTEXTEXTURESAMPLER3), D3DERR_INVALIDCALL); 2766bf215546Sopenharmony_ci 2767bf215546Sopenharmony_ci if (Sampler >= D3DDMAPSAMPLER) 2768bf215546Sopenharmony_ci Sampler = Sampler - D3DDMAPSAMPLER + NINE_MAX_SAMPLERS_PS; 2769bf215546Sopenharmony_ci 2770bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 2771bf215546Sopenharmony_ci state->samp_advertised[Sampler][Type] = Value; 2772bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_SAMPLER; 2773bf215546Sopenharmony_ci state->changed.sampler[Sampler] |= 1 << Type; 2774bf215546Sopenharmony_ci return D3D_OK; 2775bf215546Sopenharmony_ci } 2776bf215546Sopenharmony_ci 2777bf215546Sopenharmony_ci if (state->samp_advertised[Sampler][Type] == Value) 2778bf215546Sopenharmony_ci return D3D_OK; 2779bf215546Sopenharmony_ci 2780bf215546Sopenharmony_ci state->samp_advertised[Sampler][Type] = Value; 2781bf215546Sopenharmony_ci nine_context_set_sampler_state(This, Sampler, Type, Value); 2782bf215546Sopenharmony_ci 2783bf215546Sopenharmony_ci return D3D_OK; 2784bf215546Sopenharmony_ci} 2785bf215546Sopenharmony_ci 2786bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2787bf215546Sopenharmony_ciNineDevice9_ValidateDevice( struct NineDevice9 *This, 2788bf215546Sopenharmony_ci DWORD *pNumPasses ) 2789bf215546Sopenharmony_ci{ 2790bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 2791bf215546Sopenharmony_ci unsigned i; 2792bf215546Sopenharmony_ci unsigned w = 0, h = 0; 2793bf215546Sopenharmony_ci 2794bf215546Sopenharmony_ci DBG("This=%p pNumPasses=%p\n", This, pNumPasses); 2795bf215546Sopenharmony_ci 2796bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(state->samp_advertised); ++i) { 2797bf215546Sopenharmony_ci if (state->samp_advertised[i][D3DSAMP_MINFILTER] == D3DTEXF_NONE || 2798bf215546Sopenharmony_ci state->samp_advertised[i][D3DSAMP_MAGFILTER] == D3DTEXF_NONE) 2799bf215546Sopenharmony_ci return D3DERR_UNSUPPORTEDTEXTUREFILTER; 2800bf215546Sopenharmony_ci } 2801bf215546Sopenharmony_ci 2802bf215546Sopenharmony_ci for (i = 0; i < This->caps.NumSimultaneousRTs; ++i) { 2803bf215546Sopenharmony_ci if (!state->rt[i]) 2804bf215546Sopenharmony_ci continue; 2805bf215546Sopenharmony_ci if (w == 0) { 2806bf215546Sopenharmony_ci w = state->rt[i]->desc.Width; 2807bf215546Sopenharmony_ci h = state->rt[i]->desc.Height; 2808bf215546Sopenharmony_ci } else 2809bf215546Sopenharmony_ci if (state->rt[i]->desc.Width != w || state->rt[i]->desc.Height != h) { 2810bf215546Sopenharmony_ci return D3DERR_CONFLICTINGRENDERSTATE; 2811bf215546Sopenharmony_ci } 2812bf215546Sopenharmony_ci } 2813bf215546Sopenharmony_ci if (state->ds && 2814bf215546Sopenharmony_ci (state->rs_advertised[D3DRS_ZENABLE] || state->rs_advertised[D3DRS_STENCILENABLE])) { 2815bf215546Sopenharmony_ci if (w != 0 && 2816bf215546Sopenharmony_ci (state->ds->desc.Width != w || state->ds->desc.Height != h)) 2817bf215546Sopenharmony_ci return D3DERR_CONFLICTINGRENDERSTATE; 2818bf215546Sopenharmony_ci } 2819bf215546Sopenharmony_ci 2820bf215546Sopenharmony_ci if (pNumPasses) 2821bf215546Sopenharmony_ci *pNumPasses = 1; 2822bf215546Sopenharmony_ci 2823bf215546Sopenharmony_ci return D3D_OK; 2824bf215546Sopenharmony_ci} 2825bf215546Sopenharmony_ci 2826bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2827bf215546Sopenharmony_ciNineDevice9_SetPaletteEntries( struct NineDevice9 *This, 2828bf215546Sopenharmony_ci UINT PaletteNumber, 2829bf215546Sopenharmony_ci const PALETTEENTRY *pEntries ) 2830bf215546Sopenharmony_ci{ 2831bf215546Sopenharmony_ci STUB(D3D_OK); /* like wine */ 2832bf215546Sopenharmony_ci} 2833bf215546Sopenharmony_ci 2834bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2835bf215546Sopenharmony_ciNineDevice9_GetPaletteEntries( struct NineDevice9 *This, 2836bf215546Sopenharmony_ci UINT PaletteNumber, 2837bf215546Sopenharmony_ci PALETTEENTRY *pEntries ) 2838bf215546Sopenharmony_ci{ 2839bf215546Sopenharmony_ci STUB(D3DERR_INVALIDCALL); 2840bf215546Sopenharmony_ci} 2841bf215546Sopenharmony_ci 2842bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2843bf215546Sopenharmony_ciNineDevice9_SetCurrentTexturePalette( struct NineDevice9 *This, 2844bf215546Sopenharmony_ci UINT PaletteNumber ) 2845bf215546Sopenharmony_ci{ 2846bf215546Sopenharmony_ci STUB(D3D_OK); /* like wine */ 2847bf215546Sopenharmony_ci} 2848bf215546Sopenharmony_ci 2849bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2850bf215546Sopenharmony_ciNineDevice9_GetCurrentTexturePalette( struct NineDevice9 *This, 2851bf215546Sopenharmony_ci UINT *PaletteNumber ) 2852bf215546Sopenharmony_ci{ 2853bf215546Sopenharmony_ci STUB(D3DERR_INVALIDCALL); 2854bf215546Sopenharmony_ci} 2855bf215546Sopenharmony_ci 2856bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2857bf215546Sopenharmony_ciNineDevice9_SetScissorRect( struct NineDevice9 *This, 2858bf215546Sopenharmony_ci const RECT *pRect ) 2859bf215546Sopenharmony_ci{ 2860bf215546Sopenharmony_ci struct nine_state *state = This->update; 2861bf215546Sopenharmony_ci 2862bf215546Sopenharmony_ci user_assert(pRect != NULL, D3DERR_INVALIDCALL); 2863bf215546Sopenharmony_ci 2864bf215546Sopenharmony_ci DBG("x=(%u..%u) y=(%u..%u)\n", 2865bf215546Sopenharmony_ci pRect->left, pRect->top, pRect->right, pRect->bottom); 2866bf215546Sopenharmony_ci 2867bf215546Sopenharmony_ci state->scissor.minx = pRect->left; 2868bf215546Sopenharmony_ci state->scissor.miny = pRect->top; 2869bf215546Sopenharmony_ci state->scissor.maxx = pRect->right; 2870bf215546Sopenharmony_ci state->scissor.maxy = pRect->bottom; 2871bf215546Sopenharmony_ci 2872bf215546Sopenharmony_ci if (unlikely(This->is_recording)) 2873bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_SCISSOR; 2874bf215546Sopenharmony_ci else 2875bf215546Sopenharmony_ci nine_context_set_scissor(This, &state->scissor); 2876bf215546Sopenharmony_ci 2877bf215546Sopenharmony_ci return D3D_OK; 2878bf215546Sopenharmony_ci} 2879bf215546Sopenharmony_ci 2880bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2881bf215546Sopenharmony_ciNineDevice9_GetScissorRect( struct NineDevice9 *This, 2882bf215546Sopenharmony_ci RECT *pRect ) 2883bf215546Sopenharmony_ci{ 2884bf215546Sopenharmony_ci user_assert(pRect != NULL, D3DERR_INVALIDCALL); 2885bf215546Sopenharmony_ci 2886bf215546Sopenharmony_ci pRect->left = This->state.scissor.minx; 2887bf215546Sopenharmony_ci pRect->top = This->state.scissor.miny; 2888bf215546Sopenharmony_ci pRect->right = This->state.scissor.maxx; 2889bf215546Sopenharmony_ci pRect->bottom = This->state.scissor.maxy; 2890bf215546Sopenharmony_ci 2891bf215546Sopenharmony_ci return D3D_OK; 2892bf215546Sopenharmony_ci} 2893bf215546Sopenharmony_ci 2894bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2895bf215546Sopenharmony_ciNineDevice9_SetSoftwareVertexProcessing( struct NineDevice9 *This, 2896bf215546Sopenharmony_ci BOOL bSoftware ) 2897bf215546Sopenharmony_ci{ 2898bf215546Sopenharmony_ci if (This->params.BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) { 2899bf215546Sopenharmony_ci This->swvp = bSoftware; 2900bf215546Sopenharmony_ci nine_context_set_swvp(This, bSoftware); 2901bf215546Sopenharmony_ci return D3D_OK; 2902bf215546Sopenharmony_ci } else 2903bf215546Sopenharmony_ci return D3D_OK; /* msdn seems to indicate INVALIDCALL, but at least Halo expects OK */ 2904bf215546Sopenharmony_ci} 2905bf215546Sopenharmony_ci 2906bf215546Sopenharmony_ciBOOL NINE_WINAPI 2907bf215546Sopenharmony_ciNineDevice9_GetSoftwareVertexProcessing( struct NineDevice9 *This ) 2908bf215546Sopenharmony_ci{ 2909bf215546Sopenharmony_ci return This->swvp; 2910bf215546Sopenharmony_ci} 2911bf215546Sopenharmony_ci 2912bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2913bf215546Sopenharmony_ciNineDevice9_SetNPatchMode( struct NineDevice9 *This, 2914bf215546Sopenharmony_ci float nSegments ) 2915bf215546Sopenharmony_ci{ 2916bf215546Sopenharmony_ci return D3D_OK; /* Nothing to do because we don't advertise NPatch support */ 2917bf215546Sopenharmony_ci} 2918bf215546Sopenharmony_ci 2919bf215546Sopenharmony_cifloat NINE_WINAPI 2920bf215546Sopenharmony_ciNineDevice9_GetNPatchMode( struct NineDevice9 *This ) 2921bf215546Sopenharmony_ci{ 2922bf215546Sopenharmony_ci STUB(0); 2923bf215546Sopenharmony_ci} 2924bf215546Sopenharmony_ci 2925bf215546Sopenharmony_ci/* TODO: only go through dirty textures */ 2926bf215546Sopenharmony_cistatic void 2927bf215546Sopenharmony_civalidate_textures(struct NineDevice9 *device) 2928bf215546Sopenharmony_ci{ 2929bf215546Sopenharmony_ci struct NineBaseTexture9 *tex, *ptr; 2930bf215546Sopenharmony_ci LIST_FOR_EACH_ENTRY_SAFE(tex, ptr, &device->update_textures, list) { 2931bf215546Sopenharmony_ci list_delinit(&tex->list); 2932bf215546Sopenharmony_ci NineBaseTexture9_Validate(tex); 2933bf215546Sopenharmony_ci } 2934bf215546Sopenharmony_ci} 2935bf215546Sopenharmony_ci 2936bf215546Sopenharmony_cistatic void 2937bf215546Sopenharmony_ciupdate_managed_buffers(struct NineDevice9 *device) 2938bf215546Sopenharmony_ci{ 2939bf215546Sopenharmony_ci struct NineBuffer9 *buf, *ptr; 2940bf215546Sopenharmony_ci LIST_FOR_EACH_ENTRY_SAFE(buf, ptr, &device->update_buffers, managed.list) { 2941bf215546Sopenharmony_ci list_delinit(&buf->managed.list); 2942bf215546Sopenharmony_ci NineBuffer9_Upload(buf); 2943bf215546Sopenharmony_ci } 2944bf215546Sopenharmony_ci} 2945bf215546Sopenharmony_ci 2946bf215546Sopenharmony_cistatic void 2947bf215546Sopenharmony_ciNineBeforeDraw( struct NineDevice9 *This ) 2948bf215546Sopenharmony_ci{ 2949bf215546Sopenharmony_ci /* Upload Managed dirty content */ 2950bf215546Sopenharmony_ci validate_textures(This); /* may clobber state */ 2951bf215546Sopenharmony_ci update_managed_buffers(This); 2952bf215546Sopenharmony_ci} 2953bf215546Sopenharmony_ci 2954bf215546Sopenharmony_cistatic void 2955bf215546Sopenharmony_ciNineAfterDraw( struct NineDevice9 *This ) 2956bf215546Sopenharmony_ci{ 2957bf215546Sopenharmony_ci unsigned i; 2958bf215546Sopenharmony_ci struct nine_state *state = &This->state; 2959bf215546Sopenharmony_ci unsigned ps_mask = state->ps ? state->ps->rt_mask : 1; 2960bf215546Sopenharmony_ci 2961bf215546Sopenharmony_ci /* Flag render-targets with autogenmipmap for mipmap regeneration */ 2962bf215546Sopenharmony_ci for (i = 0; i < This->caps.NumSimultaneousRTs; ++i) { 2963bf215546Sopenharmony_ci struct NineSurface9 *rt = state->rt[i]; 2964bf215546Sopenharmony_ci 2965bf215546Sopenharmony_ci if (rt && rt->desc.Format != D3DFMT_NULL && (ps_mask & (1 << i)) && 2966bf215546Sopenharmony_ci rt->desc.Usage & D3DUSAGE_AUTOGENMIPMAP) { 2967bf215546Sopenharmony_ci assert(rt->texture == D3DRTYPE_TEXTURE || 2968bf215546Sopenharmony_ci rt->texture == D3DRTYPE_CUBETEXTURE); 2969bf215546Sopenharmony_ci NineBaseTexture9(rt->base.base.container)->dirty_mip = TRUE; 2970bf215546Sopenharmony_ci } 2971bf215546Sopenharmony_ci } 2972bf215546Sopenharmony_ci} 2973bf215546Sopenharmony_ci 2974bf215546Sopenharmony_ci#define IS_SYSTEMMEM_DYNAMIC(t) ((t) && (t)->base.pool == D3DPOOL_SYSTEMMEM && (t)->base.usage & D3DUSAGE_DYNAMIC) 2975bf215546Sopenharmony_ci 2976bf215546Sopenharmony_ci/* Indicates the region needed right now for these buffers and add them to the list 2977bf215546Sopenharmony_ci * of buffers to process in NineBeforeDraw. 2978bf215546Sopenharmony_ci * The reason we don't call the upload right now is to generate smaller code (no 2979bf215546Sopenharmony_ci * duplication of the NineBuffer9_Upload inline) and to have one upload (of the correct size) 2980bf215546Sopenharmony_ci * if a vertex buffer is twice input of the draw call. */ 2981bf215546Sopenharmony_cistatic void 2982bf215546Sopenharmony_ciNineTrackSystemmemDynamic( struct NineBuffer9 *This, unsigned start, unsigned width ) 2983bf215546Sopenharmony_ci{ 2984bf215546Sopenharmony_ci struct pipe_box box; 2985bf215546Sopenharmony_ci 2986bf215546Sopenharmony_ci if (start >= This->size) 2987bf215546Sopenharmony_ci return; /* outside bounds, nothing to do */ 2988bf215546Sopenharmony_ci u_box_1d(start, MIN2(width, This->size-start), &box); 2989bf215546Sopenharmony_ci u_box_union_1d(&This->managed.required_valid_region, 2990bf215546Sopenharmony_ci &This->managed.required_valid_region, 2991bf215546Sopenharmony_ci &box); 2992bf215546Sopenharmony_ci This->managed.dirty = TRUE; 2993bf215546Sopenharmony_ci BASEBUF_REGISTER_UPDATE(This); 2994bf215546Sopenharmony_ci} 2995bf215546Sopenharmony_ci 2996bf215546Sopenharmony_ciHRESULT NINE_WINAPI 2997bf215546Sopenharmony_ciNineDevice9_DrawPrimitive( struct NineDevice9 *This, 2998bf215546Sopenharmony_ci D3DPRIMITIVETYPE PrimitiveType, 2999bf215546Sopenharmony_ci UINT StartVertex, 3000bf215546Sopenharmony_ci UINT PrimitiveCount ) 3001bf215546Sopenharmony_ci{ 3002bf215546Sopenharmony_ci unsigned i; 3003bf215546Sopenharmony_ci DBG("iface %p, PrimitiveType %u, StartVertex %u, PrimitiveCount %u\n", 3004bf215546Sopenharmony_ci This, PrimitiveType, StartVertex, PrimitiveCount); 3005bf215546Sopenharmony_ci 3006bf215546Sopenharmony_ci /* Tracking for dynamic SYSTEMMEM */ 3007bf215546Sopenharmony_ci for (i = 0; i < This->caps.MaxStreams; i++) { 3008bf215546Sopenharmony_ci unsigned stride = This->state.vtxbuf[i].stride; 3009bf215546Sopenharmony_ci if (IS_SYSTEMMEM_DYNAMIC((struct NineBuffer9*)This->state.stream[i])) { 3010bf215546Sopenharmony_ci unsigned start = This->state.vtxbuf[i].buffer_offset + StartVertex * stride; 3011bf215546Sopenharmony_ci unsigned full_size = This->state.stream[i]->base.size; 3012bf215546Sopenharmony_ci unsigned num_vertices = prim_count_to_vertex_count(PrimitiveType, PrimitiveCount); 3013bf215546Sopenharmony_ci unsigned size = MIN2(full_size-start, num_vertices * stride); 3014bf215546Sopenharmony_ci if (!stride) /* Instancing. Not sure what to do. Require all */ 3015bf215546Sopenharmony_ci size = full_size; 3016bf215546Sopenharmony_ci NineTrackSystemmemDynamic(&This->state.stream[i]->base, start, size); 3017bf215546Sopenharmony_ci } 3018bf215546Sopenharmony_ci } 3019bf215546Sopenharmony_ci 3020bf215546Sopenharmony_ci NineBeforeDraw(This); 3021bf215546Sopenharmony_ci nine_context_draw_primitive(This, PrimitiveType, StartVertex, PrimitiveCount); 3022bf215546Sopenharmony_ci NineAfterDraw(This); 3023bf215546Sopenharmony_ci 3024bf215546Sopenharmony_ci return D3D_OK; 3025bf215546Sopenharmony_ci} 3026bf215546Sopenharmony_ci 3027bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3028bf215546Sopenharmony_ciNineDevice9_DrawIndexedPrimitive( struct NineDevice9 *This, 3029bf215546Sopenharmony_ci D3DPRIMITIVETYPE PrimitiveType, 3030bf215546Sopenharmony_ci INT BaseVertexIndex, 3031bf215546Sopenharmony_ci UINT MinVertexIndex, 3032bf215546Sopenharmony_ci UINT NumVertices, 3033bf215546Sopenharmony_ci UINT StartIndex, 3034bf215546Sopenharmony_ci UINT PrimitiveCount ) 3035bf215546Sopenharmony_ci{ 3036bf215546Sopenharmony_ci unsigned i, num_indices; 3037bf215546Sopenharmony_ci DBG("iface %p, PrimitiveType %u, BaseVertexIndex %u, MinVertexIndex %u " 3038bf215546Sopenharmony_ci "NumVertices %u, StartIndex %u, PrimitiveCount %u\n", 3039bf215546Sopenharmony_ci This, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, 3040bf215546Sopenharmony_ci StartIndex, PrimitiveCount); 3041bf215546Sopenharmony_ci 3042bf215546Sopenharmony_ci user_assert(This->state.idxbuf, D3DERR_INVALIDCALL); 3043bf215546Sopenharmony_ci user_assert(This->state.vdecl, D3DERR_INVALIDCALL); 3044bf215546Sopenharmony_ci 3045bf215546Sopenharmony_ci num_indices = prim_count_to_vertex_count(PrimitiveType, PrimitiveCount); 3046bf215546Sopenharmony_ci 3047bf215546Sopenharmony_ci /* Tracking for dynamic SYSTEMMEM */ 3048bf215546Sopenharmony_ci if (IS_SYSTEMMEM_DYNAMIC(&This->state.idxbuf->base)) 3049bf215546Sopenharmony_ci NineTrackSystemmemDynamic(&This->state.idxbuf->base, 3050bf215546Sopenharmony_ci StartIndex * This->state.idxbuf->index_size, 3051bf215546Sopenharmony_ci num_indices * This->state.idxbuf->index_size); 3052bf215546Sopenharmony_ci 3053bf215546Sopenharmony_ci for (i = 0; i < This->caps.MaxStreams; i++) { 3054bf215546Sopenharmony_ci if (IS_SYSTEMMEM_DYNAMIC((struct NineBuffer9*)This->state.stream[i])) { 3055bf215546Sopenharmony_ci uint32_t stride = This->state.vtxbuf[i].stride; 3056bf215546Sopenharmony_ci uint32_t full_size = This->state.stream[i]->base.size; 3057bf215546Sopenharmony_ci uint32_t start, stop; 3058bf215546Sopenharmony_ci 3059bf215546Sopenharmony_ci start = MAX2(0, This->state.vtxbuf[i].buffer_offset+(MinVertexIndex+BaseVertexIndex)*stride); 3060bf215546Sopenharmony_ci stop = This->state.vtxbuf[i].buffer_offset+(MinVertexIndex+NumVertices+BaseVertexIndex)*stride; 3061bf215546Sopenharmony_ci stop = MIN2(stop, full_size); 3062bf215546Sopenharmony_ci NineTrackSystemmemDynamic(&This->state.stream[i]->base, 3063bf215546Sopenharmony_ci start, stop-start); 3064bf215546Sopenharmony_ci } 3065bf215546Sopenharmony_ci } 3066bf215546Sopenharmony_ci 3067bf215546Sopenharmony_ci NineBeforeDraw(This); 3068bf215546Sopenharmony_ci nine_context_draw_indexed_primitive(This, PrimitiveType, BaseVertexIndex, 3069bf215546Sopenharmony_ci MinVertexIndex, NumVertices, StartIndex, 3070bf215546Sopenharmony_ci PrimitiveCount); 3071bf215546Sopenharmony_ci NineAfterDraw(This); 3072bf215546Sopenharmony_ci 3073bf215546Sopenharmony_ci return D3D_OK; 3074bf215546Sopenharmony_ci} 3075bf215546Sopenharmony_ci 3076bf215546Sopenharmony_cistatic void 3077bf215546Sopenharmony_ciNineDevice9_SetStreamSourceNULL( struct NineDevice9 *This ); 3078bf215546Sopenharmony_ci 3079bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3080bf215546Sopenharmony_ciNineDevice9_DrawPrimitiveUP( struct NineDevice9 *This, 3081bf215546Sopenharmony_ci D3DPRIMITIVETYPE PrimitiveType, 3082bf215546Sopenharmony_ci UINT PrimitiveCount, 3083bf215546Sopenharmony_ci const void *pVertexStreamZeroData, 3084bf215546Sopenharmony_ci UINT VertexStreamZeroStride ) 3085bf215546Sopenharmony_ci{ 3086bf215546Sopenharmony_ci struct pipe_resource *resource = NULL; 3087bf215546Sopenharmony_ci unsigned buffer_offset; 3088bf215546Sopenharmony_ci unsigned StartVertex = 0; 3089bf215546Sopenharmony_ci 3090bf215546Sopenharmony_ci DBG("iface %p, PrimitiveType %u, PrimitiveCount %u, data %p, stride %u\n", 3091bf215546Sopenharmony_ci This, PrimitiveType, PrimitiveCount, 3092bf215546Sopenharmony_ci pVertexStreamZeroData, VertexStreamZeroStride); 3093bf215546Sopenharmony_ci 3094bf215546Sopenharmony_ci user_assert(pVertexStreamZeroData && VertexStreamZeroStride, 3095bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3096bf215546Sopenharmony_ci user_assert(PrimitiveCount, D3D_OK); 3097bf215546Sopenharmony_ci 3098bf215546Sopenharmony_ci u_upload_data(This->vertex_uploader, 3099bf215546Sopenharmony_ci 0, 3100bf215546Sopenharmony_ci (prim_count_to_vertex_count(PrimitiveType, PrimitiveCount)) * VertexStreamZeroStride, 3101bf215546Sopenharmony_ci 1, 3102bf215546Sopenharmony_ci pVertexStreamZeroData, 3103bf215546Sopenharmony_ci &buffer_offset, 3104bf215546Sopenharmony_ci &resource); 3105bf215546Sopenharmony_ci u_upload_unmap(This->vertex_uploader); 3106bf215546Sopenharmony_ci 3107bf215546Sopenharmony_ci /* Optimization to skip changing the bound vertex buffer data 3108bf215546Sopenharmony_ci * for consecutive DrawPrimitiveUp with identical VertexStreamZeroStride */ 3109bf215546Sopenharmony_ci if (VertexStreamZeroStride > 0) { 3110bf215546Sopenharmony_ci StartVertex = buffer_offset / VertexStreamZeroStride; 3111bf215546Sopenharmony_ci buffer_offset -= StartVertex * VertexStreamZeroStride; 3112bf215546Sopenharmony_ci } 3113bf215546Sopenharmony_ci 3114bf215546Sopenharmony_ci nine_context_set_stream_source_apply(This, 0, resource, 3115bf215546Sopenharmony_ci buffer_offset, VertexStreamZeroStride); 3116bf215546Sopenharmony_ci pipe_resource_reference(&resource, NULL); 3117bf215546Sopenharmony_ci 3118bf215546Sopenharmony_ci NineBeforeDraw(This); 3119bf215546Sopenharmony_ci nine_context_draw_primitive(This, PrimitiveType, StartVertex, PrimitiveCount); 3120bf215546Sopenharmony_ci NineAfterDraw(This); 3121bf215546Sopenharmony_ci 3122bf215546Sopenharmony_ci NineDevice9_PauseRecording(This); 3123bf215546Sopenharmony_ci NineDevice9_SetStreamSourceNULL(This); 3124bf215546Sopenharmony_ci NineDevice9_ResumeRecording(This); 3125bf215546Sopenharmony_ci 3126bf215546Sopenharmony_ci return D3D_OK; 3127bf215546Sopenharmony_ci} 3128bf215546Sopenharmony_ci 3129bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3130bf215546Sopenharmony_ciNineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This, 3131bf215546Sopenharmony_ci D3DPRIMITIVETYPE PrimitiveType, 3132bf215546Sopenharmony_ci UINT MinVertexIndex, 3133bf215546Sopenharmony_ci UINT NumVertices, 3134bf215546Sopenharmony_ci UINT PrimitiveCount, 3135bf215546Sopenharmony_ci const void *pIndexData, 3136bf215546Sopenharmony_ci D3DFORMAT IndexDataFormat, 3137bf215546Sopenharmony_ci const void *pVertexStreamZeroData, 3138bf215546Sopenharmony_ci UINT VertexStreamZeroStride ) 3139bf215546Sopenharmony_ci{ 3140bf215546Sopenharmony_ci struct pipe_vertex_buffer vbuf; 3141bf215546Sopenharmony_ci unsigned index_size = (IndexDataFormat == D3DFMT_INDEX16) ? 2 : 4; 3142bf215546Sopenharmony_ci struct pipe_resource *ibuf = NULL; 3143bf215546Sopenharmony_ci unsigned base; 3144bf215546Sopenharmony_ci 3145bf215546Sopenharmony_ci DBG("iface %p, PrimitiveType %u, MinVertexIndex %u, NumVertices %u " 3146bf215546Sopenharmony_ci "PrimitiveCount %u, pIndexData %p, IndexDataFormat %u " 3147bf215546Sopenharmony_ci "pVertexStreamZeroData %p, VertexStreamZeroStride %u\n", 3148bf215546Sopenharmony_ci This, PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, 3149bf215546Sopenharmony_ci pIndexData, IndexDataFormat, 3150bf215546Sopenharmony_ci pVertexStreamZeroData, VertexStreamZeroStride); 3151bf215546Sopenharmony_ci 3152bf215546Sopenharmony_ci user_assert(pIndexData && pVertexStreamZeroData, D3DERR_INVALIDCALL); 3153bf215546Sopenharmony_ci user_assert(VertexStreamZeroStride, D3DERR_INVALIDCALL); 3154bf215546Sopenharmony_ci user_assert(IndexDataFormat == D3DFMT_INDEX16 || 3155bf215546Sopenharmony_ci IndexDataFormat == D3DFMT_INDEX32, D3DERR_INVALIDCALL); 3156bf215546Sopenharmony_ci user_assert(PrimitiveCount, D3D_OK); 3157bf215546Sopenharmony_ci 3158bf215546Sopenharmony_ci base = MinVertexIndex * VertexStreamZeroStride; 3159bf215546Sopenharmony_ci vbuf.is_user_buffer = false; 3160bf215546Sopenharmony_ci vbuf.buffer.resource = NULL; 3161bf215546Sopenharmony_ci vbuf.stride = VertexStreamZeroStride; 3162bf215546Sopenharmony_ci u_upload_data(This->vertex_uploader, 3163bf215546Sopenharmony_ci base, 3164bf215546Sopenharmony_ci NumVertices * VertexStreamZeroStride, /* XXX */ 3165bf215546Sopenharmony_ci 64, 3166bf215546Sopenharmony_ci (const uint8_t *)pVertexStreamZeroData + base, 3167bf215546Sopenharmony_ci &vbuf.buffer_offset, 3168bf215546Sopenharmony_ci &vbuf.buffer.resource); 3169bf215546Sopenharmony_ci u_upload_unmap(This->vertex_uploader); 3170bf215546Sopenharmony_ci /* Won't be used: */ 3171bf215546Sopenharmony_ci vbuf.buffer_offset -= base; 3172bf215546Sopenharmony_ci 3173bf215546Sopenharmony_ci unsigned index_offset = 0; 3174bf215546Sopenharmony_ci u_upload_data(This->pipe_secondary->stream_uploader, 3175bf215546Sopenharmony_ci 0, 3176bf215546Sopenharmony_ci (prim_count_to_vertex_count(PrimitiveType, PrimitiveCount)) * index_size, 3177bf215546Sopenharmony_ci 64, 3178bf215546Sopenharmony_ci pIndexData, 3179bf215546Sopenharmony_ci &index_offset, 3180bf215546Sopenharmony_ci &ibuf); 3181bf215546Sopenharmony_ci u_upload_unmap(This->pipe_secondary->stream_uploader); 3182bf215546Sopenharmony_ci 3183bf215546Sopenharmony_ci NineBeforeDraw(This); 3184bf215546Sopenharmony_ci nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf(This, PrimitiveType, 3185bf215546Sopenharmony_ci MinVertexIndex, 3186bf215546Sopenharmony_ci NumVertices, 3187bf215546Sopenharmony_ci PrimitiveCount, 3188bf215546Sopenharmony_ci &vbuf, 3189bf215546Sopenharmony_ci ibuf, 3190bf215546Sopenharmony_ci ibuf ? NULL : (void*)pIndexData, 3191bf215546Sopenharmony_ci index_offset, 3192bf215546Sopenharmony_ci index_size); 3193bf215546Sopenharmony_ci NineAfterDraw(This); 3194bf215546Sopenharmony_ci 3195bf215546Sopenharmony_ci pipe_vertex_buffer_unreference(&vbuf); 3196bf215546Sopenharmony_ci pipe_resource_reference(&ibuf, NULL); 3197bf215546Sopenharmony_ci 3198bf215546Sopenharmony_ci NineDevice9_PauseRecording(This); 3199bf215546Sopenharmony_ci NineDevice9_SetIndices(This, NULL); 3200bf215546Sopenharmony_ci NineDevice9_SetStreamSourceNULL(This); 3201bf215546Sopenharmony_ci NineDevice9_ResumeRecording(This); 3202bf215546Sopenharmony_ci 3203bf215546Sopenharmony_ci return D3D_OK; 3204bf215546Sopenharmony_ci} 3205bf215546Sopenharmony_ci 3206bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3207bf215546Sopenharmony_ciNineDevice9_ProcessVertices( struct NineDevice9 *This, 3208bf215546Sopenharmony_ci UINT SrcStartIndex, 3209bf215546Sopenharmony_ci UINT DestIndex, 3210bf215546Sopenharmony_ci UINT VertexCount, 3211bf215546Sopenharmony_ci IDirect3DVertexBuffer9 *pDestBuffer, 3212bf215546Sopenharmony_ci IDirect3DVertexDeclaration9 *pVertexDecl, 3213bf215546Sopenharmony_ci DWORD Flags ) 3214bf215546Sopenharmony_ci{ 3215bf215546Sopenharmony_ci struct pipe_screen *screen_sw = This->screen_sw; 3216bf215546Sopenharmony_ci struct pipe_context *pipe_sw = This->pipe_sw; 3217bf215546Sopenharmony_ci struct NineVertexDeclaration9 *vdecl = NineVertexDeclaration9(pVertexDecl); 3218bf215546Sopenharmony_ci struct NineVertexBuffer9 *dst = NineVertexBuffer9(pDestBuffer); 3219bf215546Sopenharmony_ci struct NineVertexShader9 *vs; 3220bf215546Sopenharmony_ci struct pipe_resource *resource; 3221bf215546Sopenharmony_ci struct pipe_transfer *transfer = NULL; 3222bf215546Sopenharmony_ci struct pipe_stream_output_info so; 3223bf215546Sopenharmony_ci struct pipe_stream_output_target *target; 3224bf215546Sopenharmony_ci struct pipe_draw_info draw; 3225bf215546Sopenharmony_ci struct pipe_draw_start_count_bias sc; 3226bf215546Sopenharmony_ci struct pipe_box box; 3227bf215546Sopenharmony_ci bool programmable_vs = This->state.vs && !(This->state.vdecl && This->state.vdecl->position_t); 3228bf215546Sopenharmony_ci unsigned offsets[1] = {0}; 3229bf215546Sopenharmony_ci HRESULT hr; 3230bf215546Sopenharmony_ci unsigned buffer_size; 3231bf215546Sopenharmony_ci void *map; 3232bf215546Sopenharmony_ci 3233bf215546Sopenharmony_ci DBG("This=%p SrcStartIndex=%u DestIndex=%u VertexCount=%u " 3234bf215546Sopenharmony_ci "pDestBuffer=%p pVertexDecl=%p Flags=%d\n", 3235bf215546Sopenharmony_ci This, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, 3236bf215546Sopenharmony_ci pVertexDecl, Flags); 3237bf215546Sopenharmony_ci 3238bf215546Sopenharmony_ci user_assert(pDestBuffer && pVertexDecl, D3DERR_INVALIDCALL); 3239bf215546Sopenharmony_ci 3240bf215546Sopenharmony_ci if (!screen_sw->get_param(screen_sw, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS)) { 3241bf215546Sopenharmony_ci DBG("ProcessVertices not supported\n"); 3242bf215546Sopenharmony_ci return D3DERR_INVALIDCALL; 3243bf215546Sopenharmony_ci } 3244bf215546Sopenharmony_ci 3245bf215546Sopenharmony_ci 3246bf215546Sopenharmony_ci vs = programmable_vs ? This->state.vs : This->ff.vs; 3247bf215546Sopenharmony_ci /* Note: version is 0 for ff */ 3248bf215546Sopenharmony_ci user_assert(vdecl || (vs->byte_code.version < 0x30 && dst->desc.FVF), 3249bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3250bf215546Sopenharmony_ci if (!vdecl) { 3251bf215546Sopenharmony_ci DWORD FVF = dst->desc.FVF; 3252bf215546Sopenharmony_ci vdecl = util_hash_table_get(This->ff.ht_fvf, &FVF); 3253bf215546Sopenharmony_ci if (!vdecl) { 3254bf215546Sopenharmony_ci hr = NineVertexDeclaration9_new_from_fvf(This, FVF, &vdecl); 3255bf215546Sopenharmony_ci if (FAILED(hr)) 3256bf215546Sopenharmony_ci return hr; 3257bf215546Sopenharmony_ci vdecl->fvf = FVF; 3258bf215546Sopenharmony_ci _mesa_hash_table_insert(This->ff.ht_fvf, &vdecl->fvf, vdecl); 3259bf215546Sopenharmony_ci NineUnknown_ConvertRefToBind(NineUnknown(vdecl)); 3260bf215546Sopenharmony_ci } 3261bf215546Sopenharmony_ci } 3262bf215546Sopenharmony_ci 3263bf215546Sopenharmony_ci /* Flags: Can be 0 or D3DPV_DONOTCOPYDATA, and/or lock flags 3264bf215546Sopenharmony_ci * D3DPV_DONOTCOPYDATA -> Has effect only for ff. In particular 3265bf215546Sopenharmony_ci * if not set, everything from src will be used, and dst 3266bf215546Sopenharmony_ci * must match exactly the ff vs outputs. 3267bf215546Sopenharmony_ci * TODO: Handle all the checks, etc for ff */ 3268bf215546Sopenharmony_ci user_assert(vdecl->position_t || programmable_vs, 3269bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3270bf215546Sopenharmony_ci 3271bf215546Sopenharmony_ci /* TODO: Support vs < 3 and ff */ 3272bf215546Sopenharmony_ci user_assert(vs->byte_code.version == 0x30, 3273bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3274bf215546Sopenharmony_ci /* TODO: Not hardcode the constant buffers for swvp */ 3275bf215546Sopenharmony_ci user_assert(This->may_swvp, 3276bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3277bf215546Sopenharmony_ci 3278bf215546Sopenharmony_ci nine_state_prepare_draw_sw(This, vdecl, SrcStartIndex, VertexCount, &so); 3279bf215546Sopenharmony_ci 3280bf215546Sopenharmony_ci buffer_size = VertexCount * so.stride[0] * 4; 3281bf215546Sopenharmony_ci { 3282bf215546Sopenharmony_ci struct pipe_resource templ; 3283bf215546Sopenharmony_ci 3284bf215546Sopenharmony_ci memset(&templ, 0, sizeof(templ)); 3285bf215546Sopenharmony_ci templ.target = PIPE_BUFFER; 3286bf215546Sopenharmony_ci templ.format = PIPE_FORMAT_R8_UNORM; 3287bf215546Sopenharmony_ci templ.width0 = buffer_size; 3288bf215546Sopenharmony_ci templ.flags = 0; 3289bf215546Sopenharmony_ci templ.bind = PIPE_BIND_STREAM_OUTPUT; 3290bf215546Sopenharmony_ci templ.usage = PIPE_USAGE_STREAM; 3291bf215546Sopenharmony_ci templ.height0 = templ.depth0 = templ.array_size = 1; 3292bf215546Sopenharmony_ci templ.last_level = templ.nr_samples = templ.nr_storage_samples = 0; 3293bf215546Sopenharmony_ci 3294bf215546Sopenharmony_ci resource = screen_sw->resource_create(screen_sw, &templ); 3295bf215546Sopenharmony_ci if (!resource) 3296bf215546Sopenharmony_ci return E_OUTOFMEMORY; 3297bf215546Sopenharmony_ci } 3298bf215546Sopenharmony_ci target = pipe_sw->create_stream_output_target(pipe_sw, resource, 3299bf215546Sopenharmony_ci 0, buffer_size); 3300bf215546Sopenharmony_ci if (!target) { 3301bf215546Sopenharmony_ci pipe_resource_reference(&resource, NULL); 3302bf215546Sopenharmony_ci return D3DERR_DRIVERINTERNALERROR; 3303bf215546Sopenharmony_ci } 3304bf215546Sopenharmony_ci 3305bf215546Sopenharmony_ci draw.mode = PIPE_PRIM_POINTS; 3306bf215546Sopenharmony_ci sc.count = VertexCount; 3307bf215546Sopenharmony_ci draw.start_instance = 0; 3308bf215546Sopenharmony_ci draw.primitive_restart = FALSE; 3309bf215546Sopenharmony_ci draw.restart_index = 0; 3310bf215546Sopenharmony_ci draw.instance_count = 1; 3311bf215546Sopenharmony_ci draw.index_size = 0; 3312bf215546Sopenharmony_ci sc.start = 0; 3313bf215546Sopenharmony_ci sc.index_bias = 0; 3314bf215546Sopenharmony_ci draw.min_index = 0; 3315bf215546Sopenharmony_ci draw.max_index = VertexCount - 1; 3316bf215546Sopenharmony_ci 3317bf215546Sopenharmony_ci 3318bf215546Sopenharmony_ci pipe_sw->set_stream_output_targets(pipe_sw, 1, &target, offsets); 3319bf215546Sopenharmony_ci 3320bf215546Sopenharmony_ci pipe_sw->draw_vbo(pipe_sw, &draw, 0, NULL, &sc, 1); 3321bf215546Sopenharmony_ci 3322bf215546Sopenharmony_ci pipe_sw->set_stream_output_targets(pipe_sw, 0, NULL, 0); 3323bf215546Sopenharmony_ci pipe_sw->stream_output_target_destroy(pipe_sw, target); 3324bf215546Sopenharmony_ci 3325bf215546Sopenharmony_ci u_box_1d(0, VertexCount * so.stride[0] * 4, &box); 3326bf215546Sopenharmony_ci map = pipe_sw->buffer_map(pipe_sw, resource, 0, PIPE_MAP_READ, &box, 3327bf215546Sopenharmony_ci &transfer); 3328bf215546Sopenharmony_ci if (!map) { 3329bf215546Sopenharmony_ci hr = D3DERR_DRIVERINTERNALERROR; 3330bf215546Sopenharmony_ci goto out; 3331bf215546Sopenharmony_ci } 3332bf215546Sopenharmony_ci 3333bf215546Sopenharmony_ci hr = NineVertexDeclaration9_ConvertStreamOutput(vdecl, 3334bf215546Sopenharmony_ci dst, DestIndex, VertexCount, 3335bf215546Sopenharmony_ci map, &so); 3336bf215546Sopenharmony_ci if (transfer) 3337bf215546Sopenharmony_ci pipe_sw->buffer_unmap(pipe_sw, transfer); 3338bf215546Sopenharmony_ci 3339bf215546Sopenharmony_ciout: 3340bf215546Sopenharmony_ci nine_state_after_draw_sw(This); 3341bf215546Sopenharmony_ci pipe_resource_reference(&resource, NULL); 3342bf215546Sopenharmony_ci return hr; 3343bf215546Sopenharmony_ci} 3344bf215546Sopenharmony_ci 3345bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3346bf215546Sopenharmony_ciNineDevice9_CreateVertexDeclaration( struct NineDevice9 *This, 3347bf215546Sopenharmony_ci const D3DVERTEXELEMENT9 *pVertexElements, 3348bf215546Sopenharmony_ci IDirect3DVertexDeclaration9 **ppDecl ) 3349bf215546Sopenharmony_ci{ 3350bf215546Sopenharmony_ci struct NineVertexDeclaration9 *vdecl; 3351bf215546Sopenharmony_ci 3352bf215546Sopenharmony_ci DBG("This=%p pVertexElements=%p ppDecl=%p\n", 3353bf215546Sopenharmony_ci This, pVertexElements, ppDecl); 3354bf215546Sopenharmony_ci 3355bf215546Sopenharmony_ci user_assert(pVertexElements && ppDecl, D3DERR_INVALIDCALL); 3356bf215546Sopenharmony_ci 3357bf215546Sopenharmony_ci HRESULT hr = NineVertexDeclaration9_new(This, pVertexElements, &vdecl); 3358bf215546Sopenharmony_ci if (SUCCEEDED(hr)) 3359bf215546Sopenharmony_ci *ppDecl = (IDirect3DVertexDeclaration9 *)vdecl; 3360bf215546Sopenharmony_ci 3361bf215546Sopenharmony_ci return hr; 3362bf215546Sopenharmony_ci} 3363bf215546Sopenharmony_ci 3364bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3365bf215546Sopenharmony_ciNineDevice9_SetVertexDeclaration( struct NineDevice9 *This, 3366bf215546Sopenharmony_ci IDirect3DVertexDeclaration9 *pDecl ) 3367bf215546Sopenharmony_ci{ 3368bf215546Sopenharmony_ci struct nine_state *state = This->update; 3369bf215546Sopenharmony_ci struct NineVertexDeclaration9 *vdecl = NineVertexDeclaration9(pDecl); 3370bf215546Sopenharmony_ci 3371bf215546Sopenharmony_ci DBG("This=%p pDecl=%p\n", This, pDecl); 3372bf215546Sopenharmony_ci 3373bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3374bf215546Sopenharmony_ci nine_bind(&state->vdecl, vdecl); 3375bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_VDECL; 3376bf215546Sopenharmony_ci return D3D_OK; 3377bf215546Sopenharmony_ci } 3378bf215546Sopenharmony_ci 3379bf215546Sopenharmony_ci if (state->vdecl == vdecl) 3380bf215546Sopenharmony_ci return D3D_OK; 3381bf215546Sopenharmony_ci 3382bf215546Sopenharmony_ci nine_bind(&state->vdecl, vdecl); 3383bf215546Sopenharmony_ci 3384bf215546Sopenharmony_ci nine_context_set_vertex_declaration(This, vdecl); 3385bf215546Sopenharmony_ci 3386bf215546Sopenharmony_ci return D3D_OK; 3387bf215546Sopenharmony_ci} 3388bf215546Sopenharmony_ci 3389bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3390bf215546Sopenharmony_ciNineDevice9_GetVertexDeclaration( struct NineDevice9 *This, 3391bf215546Sopenharmony_ci IDirect3DVertexDeclaration9 **ppDecl ) 3392bf215546Sopenharmony_ci{ 3393bf215546Sopenharmony_ci user_assert(ppDecl, D3DERR_INVALIDCALL); 3394bf215546Sopenharmony_ci 3395bf215546Sopenharmony_ci *ppDecl = (IDirect3DVertexDeclaration9 *)This->state.vdecl; 3396bf215546Sopenharmony_ci if (*ppDecl) 3397bf215546Sopenharmony_ci NineUnknown_AddRef(NineUnknown(*ppDecl)); 3398bf215546Sopenharmony_ci return D3D_OK; 3399bf215546Sopenharmony_ci} 3400bf215546Sopenharmony_ci 3401bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3402bf215546Sopenharmony_ciNineDevice9_SetFVF( struct NineDevice9 *This, 3403bf215546Sopenharmony_ci DWORD FVF ) 3404bf215546Sopenharmony_ci{ 3405bf215546Sopenharmony_ci struct NineVertexDeclaration9 *vdecl; 3406bf215546Sopenharmony_ci HRESULT hr; 3407bf215546Sopenharmony_ci 3408bf215546Sopenharmony_ci DBG("FVF = %08x\n", FVF); 3409bf215546Sopenharmony_ci if (!FVF) 3410bf215546Sopenharmony_ci return D3D_OK; /* like wine */ 3411bf215546Sopenharmony_ci 3412bf215546Sopenharmony_ci vdecl = util_hash_table_get(This->ff.ht_fvf, &FVF); 3413bf215546Sopenharmony_ci if (!vdecl) { 3414bf215546Sopenharmony_ci hr = NineVertexDeclaration9_new_from_fvf(This, FVF, &vdecl); 3415bf215546Sopenharmony_ci if (FAILED(hr)) 3416bf215546Sopenharmony_ci return hr; 3417bf215546Sopenharmony_ci vdecl->fvf = FVF; 3418bf215546Sopenharmony_ci _mesa_hash_table_insert(This->ff.ht_fvf, &vdecl->fvf, vdecl); 3419bf215546Sopenharmony_ci NineUnknown_ConvertRefToBind(NineUnknown(vdecl)); 3420bf215546Sopenharmony_ci } 3421bf215546Sopenharmony_ci return NineDevice9_SetVertexDeclaration( 3422bf215546Sopenharmony_ci This, (IDirect3DVertexDeclaration9 *)vdecl); 3423bf215546Sopenharmony_ci} 3424bf215546Sopenharmony_ci 3425bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3426bf215546Sopenharmony_ciNineDevice9_GetFVF( struct NineDevice9 *This, 3427bf215546Sopenharmony_ci DWORD *pFVF ) 3428bf215546Sopenharmony_ci{ 3429bf215546Sopenharmony_ci user_assert(pFVF != NULL, D3DERR_INVALIDCALL); 3430bf215546Sopenharmony_ci *pFVF = This->state.vdecl ? This->state.vdecl->fvf : 0; 3431bf215546Sopenharmony_ci return D3D_OK; 3432bf215546Sopenharmony_ci} 3433bf215546Sopenharmony_ci 3434bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3435bf215546Sopenharmony_ciNineDevice9_CreateVertexShader( struct NineDevice9 *This, 3436bf215546Sopenharmony_ci const DWORD *pFunction, 3437bf215546Sopenharmony_ci IDirect3DVertexShader9 **ppShader ) 3438bf215546Sopenharmony_ci{ 3439bf215546Sopenharmony_ci struct NineVertexShader9 *vs; 3440bf215546Sopenharmony_ci HRESULT hr; 3441bf215546Sopenharmony_ci 3442bf215546Sopenharmony_ci DBG("This=%p pFunction=%p ppShader=%p\n", This, pFunction, ppShader); 3443bf215546Sopenharmony_ci 3444bf215546Sopenharmony_ci user_assert(pFunction && ppShader, D3DERR_INVALIDCALL); 3445bf215546Sopenharmony_ci 3446bf215546Sopenharmony_ci hr = NineVertexShader9_new(This, &vs, pFunction, NULL); 3447bf215546Sopenharmony_ci if (FAILED(hr)) 3448bf215546Sopenharmony_ci return hr; 3449bf215546Sopenharmony_ci *ppShader = (IDirect3DVertexShader9 *)vs; 3450bf215546Sopenharmony_ci return D3D_OK; 3451bf215546Sopenharmony_ci} 3452bf215546Sopenharmony_ci 3453bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3454bf215546Sopenharmony_ciNineDevice9_SetVertexShader( struct NineDevice9 *This, 3455bf215546Sopenharmony_ci IDirect3DVertexShader9 *pShader ) 3456bf215546Sopenharmony_ci{ 3457bf215546Sopenharmony_ci struct nine_state *state = This->update; 3458bf215546Sopenharmony_ci struct NineVertexShader9 *vs_shader = (struct NineVertexShader9*)pShader; 3459bf215546Sopenharmony_ci 3460bf215546Sopenharmony_ci DBG("This=%p pShader=%p\n", This, pShader); 3461bf215546Sopenharmony_ci 3462bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3463bf215546Sopenharmony_ci nine_bind(&state->vs, vs_shader); 3464bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_VS; 3465bf215546Sopenharmony_ci return D3D_OK; 3466bf215546Sopenharmony_ci } 3467bf215546Sopenharmony_ci 3468bf215546Sopenharmony_ci if (state->vs == vs_shader) 3469bf215546Sopenharmony_ci return D3D_OK; 3470bf215546Sopenharmony_ci 3471bf215546Sopenharmony_ci nine_bind(&state->vs, vs_shader); 3472bf215546Sopenharmony_ci 3473bf215546Sopenharmony_ci nine_context_set_vertex_shader(This, vs_shader); 3474bf215546Sopenharmony_ci 3475bf215546Sopenharmony_ci return D3D_OK; 3476bf215546Sopenharmony_ci} 3477bf215546Sopenharmony_ci 3478bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3479bf215546Sopenharmony_ciNineDevice9_GetVertexShader( struct NineDevice9 *This, 3480bf215546Sopenharmony_ci IDirect3DVertexShader9 **ppShader ) 3481bf215546Sopenharmony_ci{ 3482bf215546Sopenharmony_ci user_assert(ppShader, D3DERR_INVALIDCALL); 3483bf215546Sopenharmony_ci nine_reference_set(ppShader, This->state.vs); 3484bf215546Sopenharmony_ci return D3D_OK; 3485bf215546Sopenharmony_ci} 3486bf215546Sopenharmony_ci 3487bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3488bf215546Sopenharmony_ciNineDevice9_SetVertexShaderConstantF( struct NineDevice9 *This, 3489bf215546Sopenharmony_ci UINT StartRegister, 3490bf215546Sopenharmony_ci const float *pConstantData, 3491bf215546Sopenharmony_ci UINT Vector4fCount ) 3492bf215546Sopenharmony_ci{ 3493bf215546Sopenharmony_ci struct nine_state *state = This->update; 3494bf215546Sopenharmony_ci float *vs_const_f = state->vs_const_f; 3495bf215546Sopenharmony_ci 3496bf215546Sopenharmony_ci DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n", 3497bf215546Sopenharmony_ci This, StartRegister, pConstantData, Vector4fCount); 3498bf215546Sopenharmony_ci 3499bf215546Sopenharmony_ci user_assert(StartRegister < This->caps.MaxVertexShaderConst, D3DERR_INVALIDCALL); 3500bf215546Sopenharmony_ci user_assert(StartRegister + Vector4fCount <= This->caps.MaxVertexShaderConst, D3DERR_INVALIDCALL); 3501bf215546Sopenharmony_ci 3502bf215546Sopenharmony_ci if (!Vector4fCount) 3503bf215546Sopenharmony_ci return D3D_OK; 3504bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 3505bf215546Sopenharmony_ci 3506bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3507bf215546Sopenharmony_ci memcpy(&vs_const_f[StartRegister * 4], 3508bf215546Sopenharmony_ci pConstantData, 3509bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->vs_const_f[0])); 3510bf215546Sopenharmony_ci 3511bf215546Sopenharmony_ci nine_ranges_insert(&state->changed.vs_const_f, 3512bf215546Sopenharmony_ci StartRegister, StartRegister + Vector4fCount, 3513bf215546Sopenharmony_ci &This->range_pool); 3514bf215546Sopenharmony_ci 3515bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_VS_CONST; 3516bf215546Sopenharmony_ci 3517bf215546Sopenharmony_ci return D3D_OK; 3518bf215546Sopenharmony_ci } 3519bf215546Sopenharmony_ci 3520bf215546Sopenharmony_ci if (!memcmp(&vs_const_f[StartRegister * 4], pConstantData, 3521bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->vs_const_f[0]))) 3522bf215546Sopenharmony_ci return D3D_OK; 3523bf215546Sopenharmony_ci 3524bf215546Sopenharmony_ci memcpy(&vs_const_f[StartRegister * 4], 3525bf215546Sopenharmony_ci pConstantData, 3526bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->vs_const_f[0])); 3527bf215546Sopenharmony_ci 3528bf215546Sopenharmony_ci nine_context_set_vertex_shader_constant_f(This, StartRegister, pConstantData, 3529bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->vs_const_f[0]), 3530bf215546Sopenharmony_ci Vector4fCount); 3531bf215546Sopenharmony_ci 3532bf215546Sopenharmony_ci return D3D_OK; 3533bf215546Sopenharmony_ci} 3534bf215546Sopenharmony_ci 3535bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3536bf215546Sopenharmony_ciNineDevice9_GetVertexShaderConstantF( struct NineDevice9 *This, 3537bf215546Sopenharmony_ci UINT StartRegister, 3538bf215546Sopenharmony_ci float *pConstantData, 3539bf215546Sopenharmony_ci UINT Vector4fCount ) 3540bf215546Sopenharmony_ci{ 3541bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 3542bf215546Sopenharmony_ci 3543bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 3544bf215546Sopenharmony_ci user_assert(StartRegister < This->caps.MaxVertexShaderConst, D3DERR_INVALIDCALL); 3545bf215546Sopenharmony_ci user_assert(StartRegister + Vector4fCount <= This->caps.MaxVertexShaderConst, D3DERR_INVALIDCALL); 3546bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 3547bf215546Sopenharmony_ci 3548bf215546Sopenharmony_ci memcpy(pConstantData, 3549bf215546Sopenharmony_ci &state->vs_const_f[StartRegister * 4], 3550bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->vs_const_f[0])); 3551bf215546Sopenharmony_ci 3552bf215546Sopenharmony_ci return D3D_OK; 3553bf215546Sopenharmony_ci} 3554bf215546Sopenharmony_ci 3555bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3556bf215546Sopenharmony_ciNineDevice9_SetVertexShaderConstantI( struct NineDevice9 *This, 3557bf215546Sopenharmony_ci UINT StartRegister, 3558bf215546Sopenharmony_ci const int *pConstantData, 3559bf215546Sopenharmony_ci UINT Vector4iCount ) 3560bf215546Sopenharmony_ci{ 3561bf215546Sopenharmony_ci struct nine_state *state = This->update; 3562bf215546Sopenharmony_ci int i; 3563bf215546Sopenharmony_ci 3564bf215546Sopenharmony_ci DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n", 3565bf215546Sopenharmony_ci This, StartRegister, pConstantData, Vector4iCount); 3566bf215546Sopenharmony_ci 3567bf215546Sopenharmony_ci user_assert(StartRegister < (This->may_swvp ? NINE_MAX_CONST_I_SWVP : NINE_MAX_CONST_I), 3568bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3569bf215546Sopenharmony_ci user_assert(StartRegister + Vector4iCount <= (This->may_swvp ? NINE_MAX_CONST_I_SWVP : NINE_MAX_CONST_I), 3570bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3571bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 3572bf215546Sopenharmony_ci 3573bf215546Sopenharmony_ci if (This->driver_caps.vs_integer) { 3574bf215546Sopenharmony_ci if (!This->is_recording) { 3575bf215546Sopenharmony_ci if (!memcmp(&state->vs_const_i[4 * StartRegister], pConstantData, 3576bf215546Sopenharmony_ci Vector4iCount * sizeof(int[4]))) 3577bf215546Sopenharmony_ci return D3D_OK; 3578bf215546Sopenharmony_ci } 3579bf215546Sopenharmony_ci memcpy(&state->vs_const_i[4 * StartRegister], 3580bf215546Sopenharmony_ci pConstantData, 3581bf215546Sopenharmony_ci Vector4iCount * sizeof(int[4])); 3582bf215546Sopenharmony_ci } else { 3583bf215546Sopenharmony_ci for (i = 0; i < Vector4iCount; i++) { 3584bf215546Sopenharmony_ci state->vs_const_i[4 * (StartRegister + i)] = fui((float)(pConstantData[4 * i])); 3585bf215546Sopenharmony_ci state->vs_const_i[4 * (StartRegister + i) + 1] = fui((float)(pConstantData[4 * i + 1])); 3586bf215546Sopenharmony_ci state->vs_const_i[4 * (StartRegister + i) + 2] = fui((float)(pConstantData[4 * i + 2])); 3587bf215546Sopenharmony_ci state->vs_const_i[4 * (StartRegister + i) + 3] = fui((float)(pConstantData[4 * i + 3])); 3588bf215546Sopenharmony_ci } 3589bf215546Sopenharmony_ci } 3590bf215546Sopenharmony_ci 3591bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3592bf215546Sopenharmony_ci nine_ranges_insert(&state->changed.vs_const_i, 3593bf215546Sopenharmony_ci StartRegister, StartRegister + Vector4iCount, 3594bf215546Sopenharmony_ci &This->range_pool); 3595bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_VS_CONST; 3596bf215546Sopenharmony_ci } else 3597bf215546Sopenharmony_ci nine_context_set_vertex_shader_constant_i(This, StartRegister, pConstantData, 3598bf215546Sopenharmony_ci Vector4iCount * sizeof(int[4]), Vector4iCount); 3599bf215546Sopenharmony_ci 3600bf215546Sopenharmony_ci return D3D_OK; 3601bf215546Sopenharmony_ci} 3602bf215546Sopenharmony_ci 3603bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3604bf215546Sopenharmony_ciNineDevice9_GetVertexShaderConstantI( struct NineDevice9 *This, 3605bf215546Sopenharmony_ci UINT StartRegister, 3606bf215546Sopenharmony_ci int *pConstantData, 3607bf215546Sopenharmony_ci UINT Vector4iCount ) 3608bf215546Sopenharmony_ci{ 3609bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 3610bf215546Sopenharmony_ci int i; 3611bf215546Sopenharmony_ci 3612bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 3613bf215546Sopenharmony_ci user_assert(StartRegister < (This->may_swvp ? NINE_MAX_CONST_I_SWVP : NINE_MAX_CONST_I), 3614bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3615bf215546Sopenharmony_ci user_assert(StartRegister + Vector4iCount <= (This->may_swvp ? NINE_MAX_CONST_I_SWVP : NINE_MAX_CONST_I), 3616bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3617bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 3618bf215546Sopenharmony_ci 3619bf215546Sopenharmony_ci if (This->driver_caps.vs_integer) { 3620bf215546Sopenharmony_ci memcpy(pConstantData, 3621bf215546Sopenharmony_ci &state->vs_const_i[4 * StartRegister], 3622bf215546Sopenharmony_ci Vector4iCount * sizeof(int[4])); 3623bf215546Sopenharmony_ci } else { 3624bf215546Sopenharmony_ci for (i = 0; i < Vector4iCount; i++) { 3625bf215546Sopenharmony_ci pConstantData[4 * i] = (int32_t) uif(state->vs_const_i[4 * (StartRegister + i)]); 3626bf215546Sopenharmony_ci pConstantData[4 * i + 1] = (int32_t) uif(state->vs_const_i[4 * (StartRegister + i) + 1]); 3627bf215546Sopenharmony_ci pConstantData[4 * i + 2] = (int32_t) uif(state->vs_const_i[4 * (StartRegister + i) + 2]); 3628bf215546Sopenharmony_ci pConstantData[4 * i + 3] = (int32_t) uif(state->vs_const_i[4 * (StartRegister + i) + 3]); 3629bf215546Sopenharmony_ci } 3630bf215546Sopenharmony_ci } 3631bf215546Sopenharmony_ci 3632bf215546Sopenharmony_ci return D3D_OK; 3633bf215546Sopenharmony_ci} 3634bf215546Sopenharmony_ci 3635bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3636bf215546Sopenharmony_ciNineDevice9_SetVertexShaderConstantB( struct NineDevice9 *This, 3637bf215546Sopenharmony_ci UINT StartRegister, 3638bf215546Sopenharmony_ci const BOOL *pConstantData, 3639bf215546Sopenharmony_ci UINT BoolCount ) 3640bf215546Sopenharmony_ci{ 3641bf215546Sopenharmony_ci struct nine_state *state = This->update; 3642bf215546Sopenharmony_ci int i; 3643bf215546Sopenharmony_ci uint32_t bool_true = This->driver_caps.vs_integer ? 0xFFFFFFFF : fui(1.0f); 3644bf215546Sopenharmony_ci 3645bf215546Sopenharmony_ci DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n", 3646bf215546Sopenharmony_ci This, StartRegister, pConstantData, BoolCount); 3647bf215546Sopenharmony_ci 3648bf215546Sopenharmony_ci user_assert(StartRegister < (This->may_swvp ? NINE_MAX_CONST_B_SWVP : NINE_MAX_CONST_B), 3649bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3650bf215546Sopenharmony_ci user_assert(StartRegister + BoolCount <= (This->may_swvp ? NINE_MAX_CONST_B_SWVP : NINE_MAX_CONST_B), 3651bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3652bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 3653bf215546Sopenharmony_ci 3654bf215546Sopenharmony_ci if (!This->is_recording) { 3655bf215546Sopenharmony_ci bool noChange = true; 3656bf215546Sopenharmony_ci for (i = 0; i < BoolCount; i++) { 3657bf215546Sopenharmony_ci if (!!state->vs_const_b[StartRegister + i] != !!pConstantData[i]) 3658bf215546Sopenharmony_ci noChange = false; 3659bf215546Sopenharmony_ci } 3660bf215546Sopenharmony_ci if (noChange) 3661bf215546Sopenharmony_ci return D3D_OK; 3662bf215546Sopenharmony_ci } 3663bf215546Sopenharmony_ci 3664bf215546Sopenharmony_ci for (i = 0; i < BoolCount; i++) 3665bf215546Sopenharmony_ci state->vs_const_b[StartRegister + i] = pConstantData[i] ? bool_true : 0; 3666bf215546Sopenharmony_ci 3667bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3668bf215546Sopenharmony_ci nine_ranges_insert(&state->changed.vs_const_b, 3669bf215546Sopenharmony_ci StartRegister, StartRegister + BoolCount, 3670bf215546Sopenharmony_ci &This->range_pool); 3671bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_VS_CONST; 3672bf215546Sopenharmony_ci } else 3673bf215546Sopenharmony_ci nine_context_set_vertex_shader_constant_b(This, StartRegister, pConstantData, 3674bf215546Sopenharmony_ci sizeof(BOOL) * BoolCount, BoolCount); 3675bf215546Sopenharmony_ci 3676bf215546Sopenharmony_ci return D3D_OK; 3677bf215546Sopenharmony_ci} 3678bf215546Sopenharmony_ci 3679bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3680bf215546Sopenharmony_ciNineDevice9_GetVertexShaderConstantB( struct NineDevice9 *This, 3681bf215546Sopenharmony_ci UINT StartRegister, 3682bf215546Sopenharmony_ci BOOL *pConstantData, 3683bf215546Sopenharmony_ci UINT BoolCount ) 3684bf215546Sopenharmony_ci{ 3685bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 3686bf215546Sopenharmony_ci int i; 3687bf215546Sopenharmony_ci 3688bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 3689bf215546Sopenharmony_ci user_assert(StartRegister < (This->may_swvp ? NINE_MAX_CONST_B_SWVP : NINE_MAX_CONST_B), 3690bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3691bf215546Sopenharmony_ci user_assert(StartRegister + BoolCount <= (This->may_swvp ? NINE_MAX_CONST_B_SWVP : NINE_MAX_CONST_B), 3692bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3693bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 3694bf215546Sopenharmony_ci 3695bf215546Sopenharmony_ci for (i = 0; i < BoolCount; i++) 3696bf215546Sopenharmony_ci pConstantData[i] = state->vs_const_b[StartRegister + i] != 0 ? TRUE : FALSE; 3697bf215546Sopenharmony_ci 3698bf215546Sopenharmony_ci return D3D_OK; 3699bf215546Sopenharmony_ci} 3700bf215546Sopenharmony_ci 3701bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3702bf215546Sopenharmony_ciNineDevice9_SetStreamSource( struct NineDevice9 *This, 3703bf215546Sopenharmony_ci UINT StreamNumber, 3704bf215546Sopenharmony_ci IDirect3DVertexBuffer9 *pStreamData, 3705bf215546Sopenharmony_ci UINT OffsetInBytes, 3706bf215546Sopenharmony_ci UINT Stride ) 3707bf215546Sopenharmony_ci{ 3708bf215546Sopenharmony_ci struct nine_state *state = This->update; 3709bf215546Sopenharmony_ci struct NineVertexBuffer9 *pVBuf9 = NineVertexBuffer9(pStreamData); 3710bf215546Sopenharmony_ci const unsigned i = StreamNumber; 3711bf215546Sopenharmony_ci 3712bf215546Sopenharmony_ci DBG("This=%p StreamNumber=%u pStreamData=%p OffsetInBytes=%u Stride=%u\n", 3713bf215546Sopenharmony_ci This, StreamNumber, pStreamData, OffsetInBytes, Stride); 3714bf215546Sopenharmony_ci 3715bf215546Sopenharmony_ci user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL); 3716bf215546Sopenharmony_ci user_assert(Stride <= This->caps.MaxStreamStride, D3DERR_INVALIDCALL); 3717bf215546Sopenharmony_ci 3718bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3719bf215546Sopenharmony_ci nine_bind(&state->stream[i], pStreamData); 3720bf215546Sopenharmony_ci state->changed.vtxbuf |= 1 << StreamNumber; 3721bf215546Sopenharmony_ci state->vtxbuf[i].stride = Stride; 3722bf215546Sopenharmony_ci state->vtxbuf[i].buffer_offset = OffsetInBytes; 3723bf215546Sopenharmony_ci return D3D_OK; 3724bf215546Sopenharmony_ci } 3725bf215546Sopenharmony_ci 3726bf215546Sopenharmony_ci if (state->stream[i] == NineVertexBuffer9(pStreamData) && 3727bf215546Sopenharmony_ci state->vtxbuf[i].stride == Stride && 3728bf215546Sopenharmony_ci state->vtxbuf[i].buffer_offset == OffsetInBytes) 3729bf215546Sopenharmony_ci return D3D_OK; 3730bf215546Sopenharmony_ci 3731bf215546Sopenharmony_ci state->vtxbuf[i].stride = Stride; 3732bf215546Sopenharmony_ci state->vtxbuf[i].buffer_offset = OffsetInBytes; 3733bf215546Sopenharmony_ci 3734bf215546Sopenharmony_ci NineBindBufferToDevice(This, 3735bf215546Sopenharmony_ci (struct NineBuffer9 **)&state->stream[i], 3736bf215546Sopenharmony_ci (struct NineBuffer9 *)pVBuf9); 3737bf215546Sopenharmony_ci 3738bf215546Sopenharmony_ci nine_context_set_stream_source(This, 3739bf215546Sopenharmony_ci StreamNumber, 3740bf215546Sopenharmony_ci pVBuf9, 3741bf215546Sopenharmony_ci OffsetInBytes, 3742bf215546Sopenharmony_ci Stride); 3743bf215546Sopenharmony_ci 3744bf215546Sopenharmony_ci return D3D_OK; 3745bf215546Sopenharmony_ci} 3746bf215546Sopenharmony_ci 3747bf215546Sopenharmony_cistatic void 3748bf215546Sopenharmony_ciNineDevice9_SetStreamSourceNULL( struct NineDevice9 *This ) 3749bf215546Sopenharmony_ci{ 3750bf215546Sopenharmony_ci struct nine_state *state = This->update; 3751bf215546Sopenharmony_ci 3752bf215546Sopenharmony_ci DBG("This=%p\n", This); 3753bf215546Sopenharmony_ci 3754bf215546Sopenharmony_ci state->vtxbuf[0].stride = 0; 3755bf215546Sopenharmony_ci state->vtxbuf[0].buffer_offset = 0; 3756bf215546Sopenharmony_ci 3757bf215546Sopenharmony_ci if (!state->stream[0]) 3758bf215546Sopenharmony_ci return; 3759bf215546Sopenharmony_ci 3760bf215546Sopenharmony_ci NineBindBufferToDevice(This, 3761bf215546Sopenharmony_ci (struct NineBuffer9 **)&state->stream[0], 3762bf215546Sopenharmony_ci NULL); 3763bf215546Sopenharmony_ci} 3764bf215546Sopenharmony_ci 3765bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3766bf215546Sopenharmony_ciNineDevice9_GetStreamSource( struct NineDevice9 *This, 3767bf215546Sopenharmony_ci UINT StreamNumber, 3768bf215546Sopenharmony_ci IDirect3DVertexBuffer9 **ppStreamData, 3769bf215546Sopenharmony_ci UINT *pOffsetInBytes, 3770bf215546Sopenharmony_ci UINT *pStride ) 3771bf215546Sopenharmony_ci{ 3772bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 3773bf215546Sopenharmony_ci const unsigned i = StreamNumber; 3774bf215546Sopenharmony_ci 3775bf215546Sopenharmony_ci user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL); 3776bf215546Sopenharmony_ci user_assert(ppStreamData && pOffsetInBytes && pStride, D3DERR_INVALIDCALL); 3777bf215546Sopenharmony_ci 3778bf215546Sopenharmony_ci nine_reference_set(ppStreamData, state->stream[i]); 3779bf215546Sopenharmony_ci *pStride = state->vtxbuf[i].stride; 3780bf215546Sopenharmony_ci *pOffsetInBytes = state->vtxbuf[i].buffer_offset; 3781bf215546Sopenharmony_ci 3782bf215546Sopenharmony_ci return D3D_OK; 3783bf215546Sopenharmony_ci} 3784bf215546Sopenharmony_ci 3785bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3786bf215546Sopenharmony_ciNineDevice9_SetStreamSourceFreq( struct NineDevice9 *This, 3787bf215546Sopenharmony_ci UINT StreamNumber, 3788bf215546Sopenharmony_ci UINT Setting ) 3789bf215546Sopenharmony_ci{ 3790bf215546Sopenharmony_ci struct nine_state *state = This->update; 3791bf215546Sopenharmony_ci /* const UINT freq = Setting & 0x7FFFFF; */ 3792bf215546Sopenharmony_ci 3793bf215546Sopenharmony_ci DBG("This=%p StreamNumber=%u FrequencyParameter=0x%x\n", This, 3794bf215546Sopenharmony_ci StreamNumber, Setting); 3795bf215546Sopenharmony_ci 3796bf215546Sopenharmony_ci user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL); 3797bf215546Sopenharmony_ci user_assert(StreamNumber != 0 || !(Setting & D3DSTREAMSOURCE_INSTANCEDATA), 3798bf215546Sopenharmony_ci D3DERR_INVALIDCALL); 3799bf215546Sopenharmony_ci user_assert(!((Setting & D3DSTREAMSOURCE_INSTANCEDATA) && 3800bf215546Sopenharmony_ci (Setting & D3DSTREAMSOURCE_INDEXEDDATA)), D3DERR_INVALIDCALL); 3801bf215546Sopenharmony_ci user_assert(Setting, D3DERR_INVALIDCALL); 3802bf215546Sopenharmony_ci 3803bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3804bf215546Sopenharmony_ci state->stream_freq[StreamNumber] = Setting; 3805bf215546Sopenharmony_ci state->changed.stream_freq |= 1 << StreamNumber; 3806bf215546Sopenharmony_ci return D3D_OK; 3807bf215546Sopenharmony_ci } 3808bf215546Sopenharmony_ci 3809bf215546Sopenharmony_ci if (state->stream_freq[StreamNumber] == Setting) 3810bf215546Sopenharmony_ci return D3D_OK; 3811bf215546Sopenharmony_ci 3812bf215546Sopenharmony_ci state->stream_freq[StreamNumber] = Setting; 3813bf215546Sopenharmony_ci 3814bf215546Sopenharmony_ci nine_context_set_stream_source_freq(This, StreamNumber, Setting); 3815bf215546Sopenharmony_ci return D3D_OK; 3816bf215546Sopenharmony_ci} 3817bf215546Sopenharmony_ci 3818bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3819bf215546Sopenharmony_ciNineDevice9_GetStreamSourceFreq( struct NineDevice9 *This, 3820bf215546Sopenharmony_ci UINT StreamNumber, 3821bf215546Sopenharmony_ci UINT *pSetting ) 3822bf215546Sopenharmony_ci{ 3823bf215546Sopenharmony_ci user_assert(pSetting != NULL, D3DERR_INVALIDCALL); 3824bf215546Sopenharmony_ci user_assert(StreamNumber < This->caps.MaxStreams, D3DERR_INVALIDCALL); 3825bf215546Sopenharmony_ci *pSetting = This->state.stream_freq[StreamNumber]; 3826bf215546Sopenharmony_ci return D3D_OK; 3827bf215546Sopenharmony_ci} 3828bf215546Sopenharmony_ci 3829bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3830bf215546Sopenharmony_ciNineDevice9_SetIndices( struct NineDevice9 *This, 3831bf215546Sopenharmony_ci IDirect3DIndexBuffer9 *pIndexData ) 3832bf215546Sopenharmony_ci{ 3833bf215546Sopenharmony_ci struct nine_state *state = This->update; 3834bf215546Sopenharmony_ci struct NineIndexBuffer9 *idxbuf = NineIndexBuffer9(pIndexData); 3835bf215546Sopenharmony_ci 3836bf215546Sopenharmony_ci DBG("This=%p pIndexData=%p\n", This, pIndexData); 3837bf215546Sopenharmony_ci 3838bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3839bf215546Sopenharmony_ci nine_bind(&state->idxbuf, idxbuf); 3840bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_IDXBUF; 3841bf215546Sopenharmony_ci return D3D_OK; 3842bf215546Sopenharmony_ci } 3843bf215546Sopenharmony_ci 3844bf215546Sopenharmony_ci if (state->idxbuf == idxbuf) 3845bf215546Sopenharmony_ci return D3D_OK; 3846bf215546Sopenharmony_ci 3847bf215546Sopenharmony_ci NineBindBufferToDevice(This, 3848bf215546Sopenharmony_ci (struct NineBuffer9 **)&state->idxbuf, 3849bf215546Sopenharmony_ci (struct NineBuffer9 *)idxbuf); 3850bf215546Sopenharmony_ci 3851bf215546Sopenharmony_ci nine_context_set_indices(This, idxbuf); 3852bf215546Sopenharmony_ci 3853bf215546Sopenharmony_ci return D3D_OK; 3854bf215546Sopenharmony_ci} 3855bf215546Sopenharmony_ci 3856bf215546Sopenharmony_ci/* XXX: wine/d3d9 doesn't have pBaseVertexIndex, and it doesn't make sense 3857bf215546Sopenharmony_ci * here because it's an argument passed to the Draw calls. 3858bf215546Sopenharmony_ci */ 3859bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3860bf215546Sopenharmony_ciNineDevice9_GetIndices( struct NineDevice9 *This, 3861bf215546Sopenharmony_ci IDirect3DIndexBuffer9 **ppIndexData) 3862bf215546Sopenharmony_ci{ 3863bf215546Sopenharmony_ci user_assert(ppIndexData, D3DERR_INVALIDCALL); 3864bf215546Sopenharmony_ci nine_reference_set(ppIndexData, This->state.idxbuf); 3865bf215546Sopenharmony_ci return D3D_OK; 3866bf215546Sopenharmony_ci} 3867bf215546Sopenharmony_ci 3868bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3869bf215546Sopenharmony_ciNineDevice9_CreatePixelShader( struct NineDevice9 *This, 3870bf215546Sopenharmony_ci const DWORD *pFunction, 3871bf215546Sopenharmony_ci IDirect3DPixelShader9 **ppShader ) 3872bf215546Sopenharmony_ci{ 3873bf215546Sopenharmony_ci struct NinePixelShader9 *ps; 3874bf215546Sopenharmony_ci HRESULT hr; 3875bf215546Sopenharmony_ci 3876bf215546Sopenharmony_ci DBG("This=%p pFunction=%p ppShader=%p\n", This, pFunction, ppShader); 3877bf215546Sopenharmony_ci 3878bf215546Sopenharmony_ci user_assert(pFunction && ppShader, D3DERR_INVALIDCALL); 3879bf215546Sopenharmony_ci 3880bf215546Sopenharmony_ci hr = NinePixelShader9_new(This, &ps, pFunction, NULL); 3881bf215546Sopenharmony_ci if (FAILED(hr)) 3882bf215546Sopenharmony_ci return hr; 3883bf215546Sopenharmony_ci *ppShader = (IDirect3DPixelShader9 *)ps; 3884bf215546Sopenharmony_ci return D3D_OK; 3885bf215546Sopenharmony_ci} 3886bf215546Sopenharmony_ci 3887bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3888bf215546Sopenharmony_ciNineDevice9_SetPixelShader( struct NineDevice9 *This, 3889bf215546Sopenharmony_ci IDirect3DPixelShader9 *pShader ) 3890bf215546Sopenharmony_ci{ 3891bf215546Sopenharmony_ci struct nine_state *state = This->update; 3892bf215546Sopenharmony_ci struct NinePixelShader9 *ps = (struct NinePixelShader9*)pShader; 3893bf215546Sopenharmony_ci 3894bf215546Sopenharmony_ci DBG("This=%p pShader=%p\n", This, pShader); 3895bf215546Sopenharmony_ci 3896bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3897bf215546Sopenharmony_ci nine_bind(&state->ps, pShader); 3898bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_PS; 3899bf215546Sopenharmony_ci return D3D_OK; 3900bf215546Sopenharmony_ci } 3901bf215546Sopenharmony_ci 3902bf215546Sopenharmony_ci if (state->ps == ps) 3903bf215546Sopenharmony_ci return D3D_OK; 3904bf215546Sopenharmony_ci 3905bf215546Sopenharmony_ci nine_bind(&state->ps, ps); 3906bf215546Sopenharmony_ci 3907bf215546Sopenharmony_ci nine_context_set_pixel_shader(This, ps); 3908bf215546Sopenharmony_ci 3909bf215546Sopenharmony_ci return D3D_OK; 3910bf215546Sopenharmony_ci} 3911bf215546Sopenharmony_ci 3912bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3913bf215546Sopenharmony_ciNineDevice9_GetPixelShader( struct NineDevice9 *This, 3914bf215546Sopenharmony_ci IDirect3DPixelShader9 **ppShader ) 3915bf215546Sopenharmony_ci{ 3916bf215546Sopenharmony_ci user_assert(ppShader, D3DERR_INVALIDCALL); 3917bf215546Sopenharmony_ci nine_reference_set(ppShader, This->state.ps); 3918bf215546Sopenharmony_ci return D3D_OK; 3919bf215546Sopenharmony_ci} 3920bf215546Sopenharmony_ci 3921bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3922bf215546Sopenharmony_ciNineDevice9_SetPixelShaderConstantF( struct NineDevice9 *This, 3923bf215546Sopenharmony_ci UINT StartRegister, 3924bf215546Sopenharmony_ci const float *pConstantData, 3925bf215546Sopenharmony_ci UINT Vector4fCount ) 3926bf215546Sopenharmony_ci{ 3927bf215546Sopenharmony_ci struct nine_state *state = This->update; 3928bf215546Sopenharmony_ci 3929bf215546Sopenharmony_ci DBG("This=%p StartRegister=%u pConstantData=%p Vector4fCount=%u\n", 3930bf215546Sopenharmony_ci This, StartRegister, pConstantData, Vector4fCount); 3931bf215546Sopenharmony_ci 3932bf215546Sopenharmony_ci user_assert(StartRegister < NINE_MAX_CONST_F_PS3, D3DERR_INVALIDCALL); 3933bf215546Sopenharmony_ci user_assert(StartRegister + Vector4fCount <= NINE_MAX_CONST_F_PS3, D3DERR_INVALIDCALL); 3934bf215546Sopenharmony_ci 3935bf215546Sopenharmony_ci if (!Vector4fCount) 3936bf215546Sopenharmony_ci return D3D_OK; 3937bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 3938bf215546Sopenharmony_ci 3939bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 3940bf215546Sopenharmony_ci memcpy(&state->ps_const_f[StartRegister * 4], 3941bf215546Sopenharmony_ci pConstantData, 3942bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->ps_const_f[0])); 3943bf215546Sopenharmony_ci 3944bf215546Sopenharmony_ci nine_ranges_insert(&state->changed.ps_const_f, 3945bf215546Sopenharmony_ci StartRegister, StartRegister + Vector4fCount, 3946bf215546Sopenharmony_ci &This->range_pool); 3947bf215546Sopenharmony_ci 3948bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_PS_CONST; 3949bf215546Sopenharmony_ci return D3D_OK; 3950bf215546Sopenharmony_ci } 3951bf215546Sopenharmony_ci 3952bf215546Sopenharmony_ci if (!memcmp(&state->ps_const_f[StartRegister * 4], pConstantData, 3953bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->ps_const_f[0]))) 3954bf215546Sopenharmony_ci return D3D_OK; 3955bf215546Sopenharmony_ci 3956bf215546Sopenharmony_ci memcpy(&state->ps_const_f[StartRegister * 4], 3957bf215546Sopenharmony_ci pConstantData, 3958bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->ps_const_f[0])); 3959bf215546Sopenharmony_ci 3960bf215546Sopenharmony_ci nine_context_set_pixel_shader_constant_f(This, StartRegister, pConstantData, 3961bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->ps_const_f[0]), 3962bf215546Sopenharmony_ci Vector4fCount); 3963bf215546Sopenharmony_ci 3964bf215546Sopenharmony_ci return D3D_OK; 3965bf215546Sopenharmony_ci} 3966bf215546Sopenharmony_ci 3967bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3968bf215546Sopenharmony_ciNineDevice9_GetPixelShaderConstantF( struct NineDevice9 *This, 3969bf215546Sopenharmony_ci UINT StartRegister, 3970bf215546Sopenharmony_ci float *pConstantData, 3971bf215546Sopenharmony_ci UINT Vector4fCount ) 3972bf215546Sopenharmony_ci{ 3973bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 3974bf215546Sopenharmony_ci 3975bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 3976bf215546Sopenharmony_ci user_assert(StartRegister < NINE_MAX_CONST_F_PS3, D3DERR_INVALIDCALL); 3977bf215546Sopenharmony_ci user_assert(StartRegister + Vector4fCount <= NINE_MAX_CONST_F_PS3, D3DERR_INVALIDCALL); 3978bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 3979bf215546Sopenharmony_ci 3980bf215546Sopenharmony_ci memcpy(pConstantData, 3981bf215546Sopenharmony_ci &state->ps_const_f[StartRegister * 4], 3982bf215546Sopenharmony_ci Vector4fCount * 4 * sizeof(state->ps_const_f[0])); 3983bf215546Sopenharmony_ci 3984bf215546Sopenharmony_ci return D3D_OK; 3985bf215546Sopenharmony_ci} 3986bf215546Sopenharmony_ci 3987bf215546Sopenharmony_ciHRESULT NINE_WINAPI 3988bf215546Sopenharmony_ciNineDevice9_SetPixelShaderConstantI( struct NineDevice9 *This, 3989bf215546Sopenharmony_ci UINT StartRegister, 3990bf215546Sopenharmony_ci const int *pConstantData, 3991bf215546Sopenharmony_ci UINT Vector4iCount ) 3992bf215546Sopenharmony_ci{ 3993bf215546Sopenharmony_ci struct nine_state *state = This->update; 3994bf215546Sopenharmony_ci int i; 3995bf215546Sopenharmony_ci 3996bf215546Sopenharmony_ci DBG("This=%p StartRegister=%u pConstantData=%p Vector4iCount=%u\n", 3997bf215546Sopenharmony_ci This, StartRegister, pConstantData, Vector4iCount); 3998bf215546Sopenharmony_ci 3999bf215546Sopenharmony_ci user_assert(StartRegister < NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 4000bf215546Sopenharmony_ci user_assert(StartRegister + Vector4iCount <= NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 4001bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 4002bf215546Sopenharmony_ci 4003bf215546Sopenharmony_ci if (This->driver_caps.ps_integer) { 4004bf215546Sopenharmony_ci if (!This->is_recording) { 4005bf215546Sopenharmony_ci if (!memcmp(&state->ps_const_i[StartRegister][0], pConstantData, 4006bf215546Sopenharmony_ci Vector4iCount * sizeof(state->ps_const_i[0]))) 4007bf215546Sopenharmony_ci return D3D_OK; 4008bf215546Sopenharmony_ci } 4009bf215546Sopenharmony_ci memcpy(&state->ps_const_i[StartRegister][0], 4010bf215546Sopenharmony_ci pConstantData, 4011bf215546Sopenharmony_ci Vector4iCount * sizeof(state->ps_const_i[0])); 4012bf215546Sopenharmony_ci } else { 4013bf215546Sopenharmony_ci for (i = 0; i < Vector4iCount; i++) { 4014bf215546Sopenharmony_ci state->ps_const_i[StartRegister+i][0] = fui((float)(pConstantData[4*i])); 4015bf215546Sopenharmony_ci state->ps_const_i[StartRegister+i][1] = fui((float)(pConstantData[4*i+1])); 4016bf215546Sopenharmony_ci state->ps_const_i[StartRegister+i][2] = fui((float)(pConstantData[4*i+2])); 4017bf215546Sopenharmony_ci state->ps_const_i[StartRegister+i][3] = fui((float)(pConstantData[4*i+3])); 4018bf215546Sopenharmony_ci } 4019bf215546Sopenharmony_ci } 4020bf215546Sopenharmony_ci 4021bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 4022bf215546Sopenharmony_ci state->changed.ps_const_i |= ((1 << Vector4iCount) - 1) << StartRegister; 4023bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_PS_CONST; 4024bf215546Sopenharmony_ci } else 4025bf215546Sopenharmony_ci nine_context_set_pixel_shader_constant_i(This, StartRegister, pConstantData, 4026bf215546Sopenharmony_ci sizeof(state->ps_const_i[0]) * Vector4iCount, Vector4iCount); 4027bf215546Sopenharmony_ci 4028bf215546Sopenharmony_ci return D3D_OK; 4029bf215546Sopenharmony_ci} 4030bf215546Sopenharmony_ci 4031bf215546Sopenharmony_ciHRESULT NINE_WINAPI 4032bf215546Sopenharmony_ciNineDevice9_GetPixelShaderConstantI( struct NineDevice9 *This, 4033bf215546Sopenharmony_ci UINT StartRegister, 4034bf215546Sopenharmony_ci int *pConstantData, 4035bf215546Sopenharmony_ci UINT Vector4iCount ) 4036bf215546Sopenharmony_ci{ 4037bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 4038bf215546Sopenharmony_ci int i; 4039bf215546Sopenharmony_ci 4040bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 4041bf215546Sopenharmony_ci user_assert(StartRegister < NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 4042bf215546Sopenharmony_ci user_assert(StartRegister + Vector4iCount <= NINE_MAX_CONST_I, D3DERR_INVALIDCALL); 4043bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 4044bf215546Sopenharmony_ci 4045bf215546Sopenharmony_ci if (This->driver_caps.ps_integer) { 4046bf215546Sopenharmony_ci memcpy(pConstantData, 4047bf215546Sopenharmony_ci &state->ps_const_i[StartRegister][0], 4048bf215546Sopenharmony_ci Vector4iCount * sizeof(state->ps_const_i[0])); 4049bf215546Sopenharmony_ci } else { 4050bf215546Sopenharmony_ci for (i = 0; i < Vector4iCount; i++) { 4051bf215546Sopenharmony_ci pConstantData[4*i] = (int32_t) uif(state->ps_const_i[StartRegister+i][0]); 4052bf215546Sopenharmony_ci pConstantData[4*i+1] = (int32_t) uif(state->ps_const_i[StartRegister+i][1]); 4053bf215546Sopenharmony_ci pConstantData[4*i+2] = (int32_t) uif(state->ps_const_i[StartRegister+i][2]); 4054bf215546Sopenharmony_ci pConstantData[4*i+3] = (int32_t) uif(state->ps_const_i[StartRegister+i][3]); 4055bf215546Sopenharmony_ci } 4056bf215546Sopenharmony_ci } 4057bf215546Sopenharmony_ci 4058bf215546Sopenharmony_ci return D3D_OK; 4059bf215546Sopenharmony_ci} 4060bf215546Sopenharmony_ci 4061bf215546Sopenharmony_ciHRESULT NINE_WINAPI 4062bf215546Sopenharmony_ciNineDevice9_SetPixelShaderConstantB( struct NineDevice9 *This, 4063bf215546Sopenharmony_ci UINT StartRegister, 4064bf215546Sopenharmony_ci const BOOL *pConstantData, 4065bf215546Sopenharmony_ci UINT BoolCount ) 4066bf215546Sopenharmony_ci{ 4067bf215546Sopenharmony_ci struct nine_state *state = This->update; 4068bf215546Sopenharmony_ci int i; 4069bf215546Sopenharmony_ci uint32_t bool_true = This->driver_caps.ps_integer ? 0xFFFFFFFF : fui(1.0f); 4070bf215546Sopenharmony_ci 4071bf215546Sopenharmony_ci DBG("This=%p StartRegister=%u pConstantData=%p BoolCount=%u\n", 4072bf215546Sopenharmony_ci This, StartRegister, pConstantData, BoolCount); 4073bf215546Sopenharmony_ci 4074bf215546Sopenharmony_ci user_assert(StartRegister < NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 4075bf215546Sopenharmony_ci user_assert(StartRegister + BoolCount <= NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 4076bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 4077bf215546Sopenharmony_ci 4078bf215546Sopenharmony_ci if (!This->is_recording) { 4079bf215546Sopenharmony_ci bool noChange = true; 4080bf215546Sopenharmony_ci for (i = 0; i < BoolCount; i++) { 4081bf215546Sopenharmony_ci if (!!state->ps_const_b[StartRegister + i] != !!pConstantData[i]) 4082bf215546Sopenharmony_ci noChange = false; 4083bf215546Sopenharmony_ci } 4084bf215546Sopenharmony_ci if (noChange) 4085bf215546Sopenharmony_ci return D3D_OK; 4086bf215546Sopenharmony_ci } 4087bf215546Sopenharmony_ci 4088bf215546Sopenharmony_ci for (i = 0; i < BoolCount; i++) 4089bf215546Sopenharmony_ci state->ps_const_b[StartRegister + i] = pConstantData[i] ? bool_true : 0; 4090bf215546Sopenharmony_ci 4091bf215546Sopenharmony_ci if (unlikely(This->is_recording)) { 4092bf215546Sopenharmony_ci state->changed.ps_const_b |= ((1 << BoolCount) - 1) << StartRegister; 4093bf215546Sopenharmony_ci state->changed.group |= NINE_STATE_PS_CONST; 4094bf215546Sopenharmony_ci } else 4095bf215546Sopenharmony_ci nine_context_set_pixel_shader_constant_b(This, StartRegister, pConstantData, 4096bf215546Sopenharmony_ci sizeof(BOOL) * BoolCount, BoolCount); 4097bf215546Sopenharmony_ci 4098bf215546Sopenharmony_ci return D3D_OK; 4099bf215546Sopenharmony_ci} 4100bf215546Sopenharmony_ci 4101bf215546Sopenharmony_ciHRESULT NINE_WINAPI 4102bf215546Sopenharmony_ciNineDevice9_GetPixelShaderConstantB( struct NineDevice9 *This, 4103bf215546Sopenharmony_ci UINT StartRegister, 4104bf215546Sopenharmony_ci BOOL *pConstantData, 4105bf215546Sopenharmony_ci UINT BoolCount ) 4106bf215546Sopenharmony_ci{ 4107bf215546Sopenharmony_ci const struct nine_state *state = &This->state; 4108bf215546Sopenharmony_ci int i; 4109bf215546Sopenharmony_ci 4110bf215546Sopenharmony_ci user_assert(!This->pure, D3DERR_INVALIDCALL); 4111bf215546Sopenharmony_ci user_assert(StartRegister < NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 4112bf215546Sopenharmony_ci user_assert(StartRegister + BoolCount <= NINE_MAX_CONST_B, D3DERR_INVALIDCALL); 4113bf215546Sopenharmony_ci user_assert(pConstantData, D3DERR_INVALIDCALL); 4114bf215546Sopenharmony_ci 4115bf215546Sopenharmony_ci for (i = 0; i < BoolCount; i++) 4116bf215546Sopenharmony_ci pConstantData[i] = state->ps_const_b[StartRegister + i] ? TRUE : FALSE; 4117bf215546Sopenharmony_ci 4118bf215546Sopenharmony_ci return D3D_OK; 4119bf215546Sopenharmony_ci} 4120bf215546Sopenharmony_ci 4121bf215546Sopenharmony_ciHRESULT NINE_WINAPI 4122bf215546Sopenharmony_ciNineDevice9_DrawRectPatch( struct NineDevice9 *This, 4123bf215546Sopenharmony_ci UINT Handle, 4124bf215546Sopenharmony_ci const float *pNumSegs, 4125bf215546Sopenharmony_ci const D3DRECTPATCH_INFO *pRectPatchInfo ) 4126bf215546Sopenharmony_ci{ 4127bf215546Sopenharmony_ci STUB(D3DERR_INVALIDCALL); 4128bf215546Sopenharmony_ci} 4129bf215546Sopenharmony_ci 4130bf215546Sopenharmony_ciHRESULT NINE_WINAPI 4131bf215546Sopenharmony_ciNineDevice9_DrawTriPatch( struct NineDevice9 *This, 4132bf215546Sopenharmony_ci UINT Handle, 4133bf215546Sopenharmony_ci const float *pNumSegs, 4134bf215546Sopenharmony_ci const D3DTRIPATCH_INFO *pTriPatchInfo ) 4135bf215546Sopenharmony_ci{ 4136bf215546Sopenharmony_ci STUB(D3DERR_INVALIDCALL); 4137bf215546Sopenharmony_ci} 4138bf215546Sopenharmony_ci 4139bf215546Sopenharmony_ciHRESULT NINE_WINAPI 4140bf215546Sopenharmony_ciNineDevice9_DeletePatch( struct NineDevice9 *This, 4141bf215546Sopenharmony_ci UINT Handle ) 4142bf215546Sopenharmony_ci{ 4143bf215546Sopenharmony_ci STUB(D3DERR_INVALIDCALL); 4144bf215546Sopenharmony_ci} 4145bf215546Sopenharmony_ci 4146bf215546Sopenharmony_ciHRESULT NINE_WINAPI 4147bf215546Sopenharmony_ciNineDevice9_CreateQuery( struct NineDevice9 *This, 4148bf215546Sopenharmony_ci D3DQUERYTYPE Type, 4149bf215546Sopenharmony_ci IDirect3DQuery9 **ppQuery ) 4150bf215546Sopenharmony_ci{ 4151bf215546Sopenharmony_ci struct NineQuery9 *query; 4152bf215546Sopenharmony_ci HRESULT hr; 4153bf215546Sopenharmony_ci 4154bf215546Sopenharmony_ci DBG("This=%p Type=%d ppQuery=%p\n", This, Type, ppQuery); 4155bf215546Sopenharmony_ci 4156bf215546Sopenharmony_ci hr = nine_is_query_supported(This->screen, Type); 4157bf215546Sopenharmony_ci if (!ppQuery || hr != D3D_OK) 4158bf215546Sopenharmony_ci return hr; 4159bf215546Sopenharmony_ci 4160bf215546Sopenharmony_ci hr = NineQuery9_new(This, &query, Type); 4161bf215546Sopenharmony_ci if (FAILED(hr)) 4162bf215546Sopenharmony_ci return hr; 4163bf215546Sopenharmony_ci *ppQuery = (IDirect3DQuery9 *)query; 4164bf215546Sopenharmony_ci return D3D_OK; 4165bf215546Sopenharmony_ci} 4166bf215546Sopenharmony_ci 4167bf215546Sopenharmony_ciIDirect3DDevice9Vtbl NineDevice9_vtable = { 4168bf215546Sopenharmony_ci (void *)NineUnknown_QueryInterface, 4169bf215546Sopenharmony_ci (void *)NineUnknown_AddRef, 4170bf215546Sopenharmony_ci (void *)NineUnknown_Release, 4171bf215546Sopenharmony_ci (void *)NineDevice9_TestCooperativeLevel, 4172bf215546Sopenharmony_ci (void *)NineDevice9_GetAvailableTextureMem, 4173bf215546Sopenharmony_ci (void *)NineDevice9_EvictManagedResources, 4174bf215546Sopenharmony_ci (void *)NineDevice9_GetDirect3D, 4175bf215546Sopenharmony_ci (void *)NineDevice9_GetDeviceCaps, 4176bf215546Sopenharmony_ci (void *)NineDevice9_GetDisplayMode, 4177bf215546Sopenharmony_ci (void *)NineDevice9_GetCreationParameters, 4178bf215546Sopenharmony_ci (void *)NineDevice9_SetCursorProperties, 4179bf215546Sopenharmony_ci (void *)NineDevice9_SetCursorPosition, 4180bf215546Sopenharmony_ci (void *)NineDevice9_ShowCursor, 4181bf215546Sopenharmony_ci (void *)NineDevice9_CreateAdditionalSwapChain, 4182bf215546Sopenharmony_ci (void *)NineDevice9_GetSwapChain, 4183bf215546Sopenharmony_ci (void *)NineDevice9_GetNumberOfSwapChains, 4184bf215546Sopenharmony_ci (void *)NineDevice9_Reset, 4185bf215546Sopenharmony_ci (void *)NineDevice9_Present, 4186bf215546Sopenharmony_ci (void *)NineDevice9_GetBackBuffer, 4187bf215546Sopenharmony_ci (void *)NineDevice9_GetRasterStatus, 4188bf215546Sopenharmony_ci (void *)NineDevice9_SetDialogBoxMode, 4189bf215546Sopenharmony_ci (void *)NineDevice9_SetGammaRamp, 4190bf215546Sopenharmony_ci (void *)NineDevice9_GetGammaRamp, 4191bf215546Sopenharmony_ci (void *)NineDevice9_CreateTexture, 4192bf215546Sopenharmony_ci (void *)NineDevice9_CreateVolumeTexture, 4193bf215546Sopenharmony_ci (void *)NineDevice9_CreateCubeTexture, 4194bf215546Sopenharmony_ci (void *)NineDevice9_CreateVertexBuffer, 4195bf215546Sopenharmony_ci (void *)NineDevice9_CreateIndexBuffer, 4196bf215546Sopenharmony_ci (void *)NineDevice9_CreateRenderTarget, 4197bf215546Sopenharmony_ci (void *)NineDevice9_CreateDepthStencilSurface, 4198bf215546Sopenharmony_ci (void *)NineDevice9_UpdateSurface, 4199bf215546Sopenharmony_ci (void *)NineDevice9_UpdateTexture, 4200bf215546Sopenharmony_ci (void *)NineDevice9_GetRenderTargetData, 4201bf215546Sopenharmony_ci (void *)NineDevice9_GetFrontBufferData, 4202bf215546Sopenharmony_ci (void *)NineDevice9_StretchRect, 4203bf215546Sopenharmony_ci (void *)NineDevice9_ColorFill, 4204bf215546Sopenharmony_ci (void *)NineDevice9_CreateOffscreenPlainSurface, 4205bf215546Sopenharmony_ci (void *)NineDevice9_SetRenderTarget, 4206bf215546Sopenharmony_ci (void *)NineDevice9_GetRenderTarget, 4207bf215546Sopenharmony_ci (void *)NineDevice9_SetDepthStencilSurface, 4208bf215546Sopenharmony_ci (void *)NineDevice9_GetDepthStencilSurface, 4209bf215546Sopenharmony_ci (void *)NineDevice9_BeginScene, 4210bf215546Sopenharmony_ci (void *)NineDevice9_EndScene, 4211bf215546Sopenharmony_ci (void *)NineDevice9_Clear, 4212bf215546Sopenharmony_ci (void *)NineDevice9_SetTransform, 4213bf215546Sopenharmony_ci (void *)NineDevice9_GetTransform, 4214bf215546Sopenharmony_ci (void *)NineDevice9_MultiplyTransform, 4215bf215546Sopenharmony_ci (void *)NineDevice9_SetViewport, 4216bf215546Sopenharmony_ci (void *)NineDevice9_GetViewport, 4217bf215546Sopenharmony_ci (void *)NineDevice9_SetMaterial, 4218bf215546Sopenharmony_ci (void *)NineDevice9_GetMaterial, 4219bf215546Sopenharmony_ci (void *)NineDevice9_SetLight, 4220bf215546Sopenharmony_ci (void *)NineDevice9_GetLight, 4221bf215546Sopenharmony_ci (void *)NineDevice9_LightEnable, 4222bf215546Sopenharmony_ci (void *)NineDevice9_GetLightEnable, 4223bf215546Sopenharmony_ci (void *)NineDevice9_SetClipPlane, 4224bf215546Sopenharmony_ci (void *)NineDevice9_GetClipPlane, 4225bf215546Sopenharmony_ci (void *)NineDevice9_SetRenderState, 4226bf215546Sopenharmony_ci (void *)NineDevice9_GetRenderState, 4227bf215546Sopenharmony_ci (void *)NineDevice9_CreateStateBlock, 4228bf215546Sopenharmony_ci (void *)NineDevice9_BeginStateBlock, 4229bf215546Sopenharmony_ci (void *)NineDevice9_EndStateBlock, 4230bf215546Sopenharmony_ci (void *)NineDevice9_SetClipStatus, 4231bf215546Sopenharmony_ci (void *)NineDevice9_GetClipStatus, 4232bf215546Sopenharmony_ci (void *)NineDevice9_GetTexture, 4233bf215546Sopenharmony_ci (void *)NineDevice9_SetTexture, 4234bf215546Sopenharmony_ci (void *)NineDevice9_GetTextureStageState, 4235bf215546Sopenharmony_ci (void *)NineDevice9_SetTextureStageState, 4236bf215546Sopenharmony_ci (void *)NineDevice9_GetSamplerState, 4237bf215546Sopenharmony_ci (void *)NineDevice9_SetSamplerState, 4238bf215546Sopenharmony_ci (void *)NineDevice9_ValidateDevice, 4239bf215546Sopenharmony_ci (void *)NineDevice9_SetPaletteEntries, 4240bf215546Sopenharmony_ci (void *)NineDevice9_GetPaletteEntries, 4241bf215546Sopenharmony_ci (void *)NineDevice9_SetCurrentTexturePalette, 4242bf215546Sopenharmony_ci (void *)NineDevice9_GetCurrentTexturePalette, 4243bf215546Sopenharmony_ci (void *)NineDevice9_SetScissorRect, 4244bf215546Sopenharmony_ci (void *)NineDevice9_GetScissorRect, 4245bf215546Sopenharmony_ci (void *)NineDevice9_SetSoftwareVertexProcessing, 4246bf215546Sopenharmony_ci (void *)NineDevice9_GetSoftwareVertexProcessing, 4247bf215546Sopenharmony_ci (void *)NineDevice9_SetNPatchMode, 4248bf215546Sopenharmony_ci (void *)NineDevice9_GetNPatchMode, 4249bf215546Sopenharmony_ci (void *)NineDevice9_DrawPrimitive, 4250bf215546Sopenharmony_ci (void *)NineDevice9_DrawIndexedPrimitive, 4251bf215546Sopenharmony_ci (void *)NineDevice9_DrawPrimitiveUP, 4252bf215546Sopenharmony_ci (void *)NineDevice9_DrawIndexedPrimitiveUP, 4253bf215546Sopenharmony_ci (void *)NineDevice9_ProcessVertices, 4254bf215546Sopenharmony_ci (void *)NineDevice9_CreateVertexDeclaration, 4255bf215546Sopenharmony_ci (void *)NineDevice9_SetVertexDeclaration, 4256bf215546Sopenharmony_ci (void *)NineDevice9_GetVertexDeclaration, 4257bf215546Sopenharmony_ci (void *)NineDevice9_SetFVF, 4258bf215546Sopenharmony_ci (void *)NineDevice9_GetFVF, 4259bf215546Sopenharmony_ci (void *)NineDevice9_CreateVertexShader, 4260bf215546Sopenharmony_ci (void *)NineDevice9_SetVertexShader, 4261bf215546Sopenharmony_ci (void *)NineDevice9_GetVertexShader, 4262bf215546Sopenharmony_ci (void *)NineDevice9_SetVertexShaderConstantF, 4263bf215546Sopenharmony_ci (void *)NineDevice9_GetVertexShaderConstantF, 4264bf215546Sopenharmony_ci (void *)NineDevice9_SetVertexShaderConstantI, 4265bf215546Sopenharmony_ci (void *)NineDevice9_GetVertexShaderConstantI, 4266bf215546Sopenharmony_ci (void *)NineDevice9_SetVertexShaderConstantB, 4267bf215546Sopenharmony_ci (void *)NineDevice9_GetVertexShaderConstantB, 4268bf215546Sopenharmony_ci (void *)NineDevice9_SetStreamSource, 4269bf215546Sopenharmony_ci (void *)NineDevice9_GetStreamSource, 4270bf215546Sopenharmony_ci (void *)NineDevice9_SetStreamSourceFreq, 4271bf215546Sopenharmony_ci (void *)NineDevice9_GetStreamSourceFreq, 4272bf215546Sopenharmony_ci (void *)NineDevice9_SetIndices, 4273bf215546Sopenharmony_ci (void *)NineDevice9_GetIndices, 4274bf215546Sopenharmony_ci (void *)NineDevice9_CreatePixelShader, 4275bf215546Sopenharmony_ci (void *)NineDevice9_SetPixelShader, 4276bf215546Sopenharmony_ci (void *)NineDevice9_GetPixelShader, 4277bf215546Sopenharmony_ci (void *)NineDevice9_SetPixelShaderConstantF, 4278bf215546Sopenharmony_ci (void *)NineDevice9_GetPixelShaderConstantF, 4279bf215546Sopenharmony_ci (void *)NineDevice9_SetPixelShaderConstantI, 4280bf215546Sopenharmony_ci (void *)NineDevice9_GetPixelShaderConstantI, 4281bf215546Sopenharmony_ci (void *)NineDevice9_SetPixelShaderConstantB, 4282bf215546Sopenharmony_ci (void *)NineDevice9_GetPixelShaderConstantB, 4283bf215546Sopenharmony_ci (void *)NineDevice9_DrawRectPatch, 4284bf215546Sopenharmony_ci (void *)NineDevice9_DrawTriPatch, 4285bf215546Sopenharmony_ci (void *)NineDevice9_DeletePatch, 4286bf215546Sopenharmony_ci (void *)NineDevice9_CreateQuery 4287bf215546Sopenharmony_ci}; 4288bf215546Sopenharmony_ci 4289bf215546Sopenharmony_cistatic const GUID *NineDevice9_IIDs[] = { 4290bf215546Sopenharmony_ci &IID_IDirect3DDevice9, 4291bf215546Sopenharmony_ci &IID_IUnknown, 4292bf215546Sopenharmony_ci NULL 4293bf215546Sopenharmony_ci}; 4294bf215546Sopenharmony_ci 4295bf215546Sopenharmony_ciHRESULT 4296bf215546Sopenharmony_ciNineDevice9_new( struct pipe_screen *pScreen, 4297bf215546Sopenharmony_ci D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, 4298bf215546Sopenharmony_ci D3DCAPS9 *pCaps, 4299bf215546Sopenharmony_ci D3DPRESENT_PARAMETERS *pPresentationParameters, 4300bf215546Sopenharmony_ci IDirect3D9 *pD3D9, 4301bf215546Sopenharmony_ci ID3DPresentGroup *pPresentationGroup, 4302bf215546Sopenharmony_ci struct d3dadapter9_context *pCTX, 4303bf215546Sopenharmony_ci boolean ex, 4304bf215546Sopenharmony_ci D3DDISPLAYMODEEX *pFullscreenDisplayMode, 4305bf215546Sopenharmony_ci struct NineDevice9 **ppOut, 4306bf215546Sopenharmony_ci int minorVersionNum ) 4307bf215546Sopenharmony_ci{ 4308bf215546Sopenharmony_ci BOOL lock; 4309bf215546Sopenharmony_ci lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED); 4310bf215546Sopenharmony_ci 4311bf215546Sopenharmony_ci NINE_NEW(Device9, ppOut, lock, /* args */ 4312bf215546Sopenharmony_ci pScreen, pCreationParameters, pCaps, 4313bf215546Sopenharmony_ci pPresentationParameters, pD3D9, pPresentationGroup, pCTX, 4314bf215546Sopenharmony_ci ex, pFullscreenDisplayMode, minorVersionNum ); 4315bf215546Sopenharmony_ci} 4316