HRESULT NinePixelShader9_ctor( struct NinePixelShader9 *This, struct NineUnknownParams *pParams, const DWORD *pFunction, void *cso ) { struct NineDevice9 *device; struct nine_shader_info info; struct pipe_context *pipe; HRESULT hr; DBG("This=%p pParams=%p pFunction=%p cso=%p\n", This, pParams, pFunction, cso); hr = NineUnknown_ctor(&This->base, pParams); if (FAILED(hr)) return hr; if (cso) { This->ff_cso = cso; return D3D_OK; } device = This->base.device; info.type = PIPE_SHADER_FRAGMENT; info.byte_code = pFunction; info.const_i_base = NINE_CONST_I_BASE(device->max_ps_const_f) / 16; info.const_b_base = NINE_CONST_B_BASE(device->max_ps_const_f) / 16; info.sampler_mask_shadow = 0x0; info.sampler_ps1xtypes = 0x0; info.fog_enable = 0; info.projected = 0; info.process_vertices = false; pipe = nine_context_get_pipe_acquire(device); hr = nine_translate_shader(device, &info, pipe); nine_context_get_pipe_release(device); if (FAILED(hr)) return hr; This->byte_code.version = info.version; This->byte_code.tokens = mem_dup(pFunction, info.byte_size); if (!This->byte_code.tokens) return E_OUTOFMEMORY; This->byte_code.size = info.byte_size; This->variant.cso = info.cso; This->last_cso = info.cso; This->last_key = 0; This->sampler_mask = info.sampler_mask; This->rt_mask = info.rt_mask; This->const_used_size = info.const_used_size; This->bumpenvmat_needed = info.bumpenvmat_needed; /* no constant relative addressing for ps */ assert(info.lconstf.data == NULL); assert(info.lconstf.ranges == NULL); return D3D_OK; }
static D3DWindowBuffer * D3DWindowBuffer_create(struct NineSwapChain9 *This, struct pipe_resource *resource, int depth, int for_frontbuffer_reading) { D3DWindowBuffer *ret; struct pipe_context *pipe = nine_context_get_pipe_acquire(This->base.device); struct winsys_handle whandle; int stride, dmaBufFd; HRESULT hr; memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_FD; This->screen->resource_get_handle(This->screen, pipe, resource, &whandle, for_frontbuffer_reading ? PIPE_HANDLE_USAGE_WRITE : PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ); nine_context_get_pipe_release(This->base.device); stride = whandle.stride; dmaBufFd = whandle.handle; hr = ID3DPresent_NewD3DWindowBufferFromDmaBuf(This->present, dmaBufFd, resource->width0, resource->height0, stride, depth, 32, &ret); assert (SUCCEEDED(hr)); if (FAILED(hr)) { ERR("Failed to create new D3DWindowBufferFromDmaBuf\n"); return NULL; } return ret; }
HRESULT NineBaseTexture9_UpdateSamplerView( struct NineBaseTexture9 *This, const int sRGB ) { const struct util_format_description *desc; struct pipe_context *pipe; struct pipe_screen *screen = NineDevice9_GetScreen(This->base.base.device); struct pipe_resource *resource = This->base.resource; struct pipe_sampler_view templ; enum pipe_format srgb_format; unsigned i; uint8_t swizzle[4]; DBG("This=%p sRGB=%d\n", This, sRGB); if (unlikely(!resource)) { if (unlikely(This->format == D3DFMT_NULL)) return D3D_OK; NineBaseTexture9_Dump(This); } assert(resource); pipe_sampler_view_reference(&This->view[sRGB], NULL); swizzle[0] = PIPE_SWIZZLE_X; swizzle[1] = PIPE_SWIZZLE_Y; swizzle[2] = PIPE_SWIZZLE_Z; swizzle[3] = PIPE_SWIZZLE_W; desc = util_format_description(resource->format); if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { /* msdn doc is incomplete here and wrong. * The only formats that can be read directly here * are DF16, DF24 and INTZ. * Tested on win the swizzle is * R = depth, G = B = 0, A = 1 for DF16 and DF24 * R = G = B = A = depth for INTZ * For the other ZS formats that can't be read directly * but can be used as shadow map, the result is duplicated on * all channel */ if (This->format == D3DFMT_DF16 || This->format == D3DFMT_DF24) { swizzle[1] = PIPE_SWIZZLE_0; swizzle[2] = PIPE_SWIZZLE_0; swizzle[3] = PIPE_SWIZZLE_1; } else { swizzle[1] = PIPE_SWIZZLE_X; swizzle[2] = PIPE_SWIZZLE_X; swizzle[3] = PIPE_SWIZZLE_X; } } else if (resource->format == PIPE_FORMAT_RGTC2_UNORM) { swizzle[0] = PIPE_SWIZZLE_Y; swizzle[1] = PIPE_SWIZZLE_X; swizzle[2] = PIPE_SWIZZLE_1; swizzle[3] = PIPE_SWIZZLE_1; } else if (resource->format != PIPE_FORMAT_A8_UNORM && resource->format != PIPE_FORMAT_RGTC1_UNORM) { /* exceptions: * A8 should have 0.0 as default values for RGB. * ATI1/RGTC1 should be r 0 0 1 (tested on windows). * It is already what gallium does. All the other ones * should have 1.0 for non-defined values */ for (i = 0; i < 4; i++) { if (SWIZZLE_TO_REPLACE(desc->swizzle[i])) swizzle[i] = PIPE_SWIZZLE_1; } } /* if requested and supported, convert to the sRGB format */ srgb_format = util_format_srgb(resource->format); if (sRGB && srgb_format != PIPE_FORMAT_NONE && screen->is_format_supported(screen, srgb_format, resource->target, 0, 0, resource->bind)) templ.format = srgb_format; else templ.format = resource->format; templ.u.tex.first_layer = 0; templ.u.tex.last_layer = resource->target == PIPE_TEXTURE_3D ? resource->depth0 - 1 : resource->array_size - 1; templ.u.tex.first_level = 0; templ.u.tex.last_level = resource->last_level; templ.swizzle_r = swizzle[0]; templ.swizzle_g = swizzle[1]; templ.swizzle_b = swizzle[2]; templ.swizzle_a = swizzle[3]; templ.target = resource->target; pipe = nine_context_get_pipe_acquire(This->base.base.device); This->view[sRGB] = pipe->create_sampler_view(pipe, resource, &templ); nine_context_get_pipe_release(This->base.base.device); DBG("sampler view = %p(resource = %p)\n", This->view[sRGB], resource); return This->view ? D3D_OK : D3DERR_DRIVERINTERNALERROR; }
HRESULT NineBaseTexture9_CreatePipeResource( struct NineBaseTexture9 *This, BOOL CopyData ) { struct pipe_context *pipe; struct pipe_screen *screen = This->base.info.screen; struct pipe_resource templ; unsigned l, m; struct pipe_resource *res; struct pipe_resource *old = This->base.resource; DBG("This=%p lod=%u last_level=%u\n", This, This->managed.lod, This->base.info.last_level); assert(This->base.pool == D3DPOOL_MANAGED); templ = This->base.info; if (This->managed.lod) { templ.width0 = u_minify(templ.width0, This->managed.lod); templ.height0 = u_minify(templ.height0, This->managed.lod); templ.depth0 = u_minify(templ.depth0, This->managed.lod); } templ.last_level = This->base.info.last_level - This->managed.lod; if (old) { /* LOD might have changed. */ if (old->width0 == templ.width0 && old->height0 == templ.height0 && old->depth0 == templ.depth0) return D3D_OK; } res = screen->resource_create(screen, &templ); if (!res) return D3DERR_OUTOFVIDEOMEMORY; This->base.resource = res; if (old && CopyData) { /* Don't return without releasing old ! */ struct pipe_box box; box.x = 0; box.y = 0; box.z = 0; l = (This->managed.lod < This->managed.lod_resident) ? This->managed.lod_resident - This->managed.lod : 0; m = (This->managed.lod < This->managed.lod_resident) ? 0 : This->managed.lod - This->managed.lod_resident; box.width = u_minify(templ.width0, l); box.height = u_minify(templ.height0, l); box.depth = u_minify(templ.depth0, l); pipe = nine_context_get_pipe_acquire(This->base.base.device); for (; l <= templ.last_level; ++l, ++m) { pipe->resource_copy_region(pipe, res, l, 0, 0, 0, old, m, &box); box.width = u_minify(box.width, 1); box.height = u_minify(box.height, 1); box.depth = u_minify(box.depth, 1); } nine_context_get_pipe_release(This->base.base.device); } pipe_resource_reference(&old, NULL); return D3D_OK; }