static HRESULT NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This, struct NineUnknownParams *pParams, UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, HANDLE *pSharedHandle ) { struct pipe_resource *info = &This->base.base.info; struct pipe_screen *screen = pParams->device->screen; enum pipe_format pf; unsigned l; D3DVOLUME_DESC voldesc; HRESULT hr; DBG("This=%p pParams=%p Width=%u Height=%u Depth=%u Levels=%u " "Usage=%d Format=%d Pool=%d pSharedHandle=%p\n", This, pParams, Width, Height, Depth, Levels, Usage, Format, Pool, pSharedHandle); user_assert(Width && Height && Depth, D3DERR_INVALIDCALL); /* user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); */ user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */ /* An IDirect3DVolume9 cannot be bound as a render target can it ? */ user_assert(!(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)), D3DERR_INVALIDCALL); user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP), D3DERR_INVALIDCALL); pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW, FALSE, Pool == D3DPOOL_SCRATCH); if (pf == PIPE_FORMAT_NONE) return D3DERR_INVALIDCALL; /* We support ATI1 and ATI2 hacks only for 2D and Cube textures */ if (Format == D3DFMT_ATI1 || Format == D3DFMT_ATI2) return D3DERR_INVALIDCALL; if (compressed_format(Format)) { const unsigned w = util_format_get_blockwidth(pf); const unsigned h = util_format_get_blockheight(pf); /* Compressed formats are not compressed on depth component */ user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL); } info->screen = pParams->device->screen; info->target = PIPE_TEXTURE_3D; info->format = pf; info->width0 = Width; info->height0 = Height; info->depth0 = Depth; if (Levels) info->last_level = Levels - 1; else info->last_level = util_logbase2(MAX2(MAX2(Width, Height), Depth)); info->array_size = 1; info->nr_samples = 0; info->bind = PIPE_BIND_SAMPLER_VIEW; info->usage = PIPE_USAGE_DEFAULT; info->flags = 0; if (Usage & D3DUSAGE_DYNAMIC) { info->usage = PIPE_USAGE_DYNAMIC; info->bind |= PIPE_BIND_TRANSFER_READ | PIPE_BIND_TRANSFER_WRITE; } if (Usage & D3DUSAGE_SOFTWAREPROCESSING) DBG("Application asked for Software Vertex Processing, " "but this is unimplemented\n"); This->volumes = CALLOC(info->last_level + 1, sizeof(*This->volumes)); if (!This->volumes) return E_OUTOFMEMORY; This->base.pstype = 3; hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_VOLUMETEXTURE, Format, Pool, Usage); if (FAILED(hr)) return hr; voldesc.Format = Format; voldesc.Type = D3DRTYPE_VOLUME; voldesc.Usage = Usage; voldesc.Pool = Pool; for (l = 0; l <= info->last_level; ++l) { voldesc.Width = u_minify(Width, l); voldesc.Height = u_minify(Height, l); voldesc.Depth = u_minify(Depth, l); hr = NineVolume9_new(This->base.base.base.device, NineUnknown(This), This->base.base.resource, l, &voldesc, &This->volumes[l]); if (FAILED(hr)) return hr; } /* Textures start initially dirty */ NineVolumeTexture9_AddDirtyBox(This, NULL); return D3D_OK; }
HRESULT NineSurface9_ctor( struct NineSurface9 *This, struct NineUnknownParams *pParams, struct NineUnknown *pContainer, struct pipe_resource *pResource, void *user_buffer, uint8_t TextureType, unsigned Level, unsigned Layer, D3DSURFACE_DESC *pDesc ) { HRESULT hr; union pipe_color_union rgba = {0}; struct pipe_surface *surf; struct pipe_context *pipe = pParams->device->pipe; bool allocate = !pContainer && pDesc->Format != D3DFMT_NULL; D3DMULTISAMPLE_TYPE multisample_type; DBG("This=%p pDevice=%p pResource=%p Level=%u Layer=%u pDesc=%p\n", This, pParams->device, pResource, Level, Layer, pDesc); /* Mark this as a special surface held by another internal resource. */ pParams->container = pContainer; /* Make sure there's a Desc */ assert(pDesc); /* D3DUSAGE_DYNAMIC isn't allowed on managed buffers */ user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) || (pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL); assert(allocate || pResource || user_buffer || pDesc->Format == D3DFMT_NULL); assert(!allocate || (!pResource && !user_buffer)); assert(!pResource || !user_buffer); assert(!user_buffer || pDesc->Pool != D3DPOOL_DEFAULT); assert(!pResource || pDesc->Pool == D3DPOOL_DEFAULT); /* Allocation only from create_zs_or_rt_surface with params 0 0 0 */ assert(!allocate || (Level == 0 && Layer == 0 && TextureType == 0)); This->data = (uint8_t *)user_buffer; multisample_type = pDesc->MultiSampleType; /* Map MultiSampleQuality to MultiSampleType */ hr = d3dmultisample_type_check(pParams->device->screen, pDesc->Format, &multisample_type, pDesc->MultiSampleQuality, NULL); if (FAILED(hr)) { return hr; } /* TODO: this is (except width and height) duplicate from * container info (in the pContainer case). Some refactoring is * needed to avoid duplication */ This->base.info.screen = pParams->device->screen; This->base.info.target = PIPE_TEXTURE_2D; This->base.info.width0 = pDesc->Width; This->base.info.height0 = pDesc->Height; This->base.info.depth0 = 1; This->base.info.last_level = 0; This->base.info.array_size = 1; This->base.info.nr_samples = multisample_type; This->base.info.usage = PIPE_USAGE_DEFAULT; This->base.info.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */ if (pDesc->Usage & D3DUSAGE_RENDERTARGET) { This->base.info.bind |= PIPE_BIND_RENDER_TARGET; } else if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL) { This->base.info.bind = d3d9_get_pipe_depth_format_bindings(pDesc->Format); if (TextureType) This->base.info.bind |= PIPE_BIND_SAMPLER_VIEW; } This->base.info.flags = 0; This->base.info.format = d3d9_to_pipe_format_checked(This->base.info.screen, pDesc->Format, This->base.info.target, This->base.info.nr_samples, This->base.info.bind, FALSE, pDesc->Pool == D3DPOOL_SCRATCH); if (This->base.info.format == PIPE_FORMAT_NONE && pDesc->Format != D3DFMT_NULL) return D3DERR_INVALIDCALL; if (allocate && compressed_format(pDesc->Format)) { const unsigned w = util_format_get_blockwidth(This->base.info.format); const unsigned h = util_format_get_blockheight(This->base.info.format); /* Note: In the !allocate case, the test could fail (lower levels of a texture) */ user_assert(!(pDesc->Width % w) && !(pDesc->Height % h), D3DERR_INVALIDCALL); } /* Get true format */ This->format_conversion = d3d9_to_pipe_format_checked(This->base.info.screen, pDesc->Format, This->base.info.target, This->base.info.nr_samples, This->base.info.bind, FALSE, TRUE); if (This->base.info.format != This->format_conversion) { This->data_conversion = align_calloc( nine_format_get_level_alloc_size(This->format_conversion, pDesc->Width, pDesc->Height, 0), 32); if (!This->data_conversion) return E_OUTOFMEMORY; This->stride_conversion = nine_format_get_stride(This->format_conversion, pDesc->Width); } if ((allocate && pDesc->Pool != D3DPOOL_DEFAULT) || pDesc->Format == D3DFMT_NULL) { /* Ram buffer with no parent. Has to allocate the resource itself */ assert(!user_buffer); This->data = align_calloc( nine_format_get_level_alloc_size(This->base.info.format, pDesc->Width, pDesc->Height, 0), 32); if (!This->data) return E_OUTOFMEMORY; } hr = NineResource9_ctor(&This->base, pParams, pResource, allocate && (pDesc->Pool == D3DPOOL_DEFAULT), D3DRTYPE_SURFACE, pDesc->Pool, pDesc->Usage); if (FAILED(hr)) return hr; This->pipe = This->base.base.device->pipe; This->transfer = NULL; This->texture = TextureType; This->level = Level; This->level_actual = Level; This->layer = Layer; This->desc = *pDesc; This->stride = nine_format_get_stride(This->base.info.format, pDesc->Width); if (This->base.resource && (pDesc->Usage & D3DUSAGE_DYNAMIC)) This->base.resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; /* TODO: investigate what else exactly needs to be cleared */ if (This->base.resource && (pDesc->Usage & D3DUSAGE_RENDERTARGET)) { surf = NineSurface9_GetSurface(This, 0); pipe->clear_render_target(pipe, surf, &rgba, 0, 0, pDesc->Width, pDesc->Height, false); } NineSurface9_Dump(This); return D3D_OK; }
static HRESULT NineTexture9_ctor( struct NineTexture9 *This, struct NineUnknownParams *pParams, UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, HANDLE *pSharedHandle ) { struct pipe_screen *screen = pParams->device->screen; struct pipe_resource *info = &This->base.base.info; enum pipe_format pf; unsigned *level_offsets; unsigned l; D3DSURFACE_DESC sfdesc; HRESULT hr; void *user_buffer = NULL, *user_buffer_for_level; DBG("(%p) Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s " "pSharedHandle=%p\n", This, Width, Height, Levels, nine_D3DUSAGE_to_str(Usage), d3dformat_to_string(Format), nine_D3DPOOL_to_str(Pool), pSharedHandle); user_assert(Width && Height, D3DERR_INVALIDCALL); /* pSharedHandle: can be non-null for ex only. * D3DPOOL_SYSTEMMEM: Levels must be 1 * D3DPOOL_DEFAULT: no restriction for Levels * Other Pools are forbidden. */ user_assert(!pSharedHandle || pParams->device->ex, D3DERR_INVALIDCALL); user_assert(!pSharedHandle || (Pool == D3DPOOL_SYSTEMMEM && Levels == 1) || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) || (Pool != D3DPOOL_SYSTEMMEM && Pool != D3DPOOL_SCRATCH && Levels <= 1), D3DERR_INVALIDCALL); /* TODO: implement pSharedHandle for D3DPOOL_DEFAULT (cross process * buffer sharing). * * Gem names may have fit but they're depreciated and won't work on render-nodes. * One solution is to use shm buffers. We would use a /dev/shm file, fill the first * values to tell it is a nine buffer, the size, which function created it, etc, * and then it would contain the data. The handle would be a number, corresponding to * the file to read (/dev/shm/nine-share-4 for example would be 4). * * Wine just ignores the argument, which works only if the app creates the handle * and won't use it. Instead of failing, we support that situation by putting an * invalid handle, that we would fail to import. Please note that we don't advertise * the flag indicating the support for that feature, but apps seem to not care. */ if (pSharedHandle && Pool == D3DPOOL_DEFAULT) { if (!*pSharedHandle) { DBG("Creating Texture with invalid handle. Importing will fail\n."); *pSharedHandle = (HANDLE)1; /* Wine would keep it NULL */ pSharedHandle = NULL; } else { ERR("Application tries to use cross-process sharing feature. Nine " "doesn't support it"); return D3DERR_INVALIDCALL; } } if (Usage & D3DUSAGE_AUTOGENMIPMAP) Levels = 0; pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, FALSE, Pool == D3DPOOL_SCRATCH); if (Format != D3DFMT_NULL && pf == PIPE_FORMAT_NONE) return D3DERR_INVALIDCALL; if (compressed_format(Format)) { const unsigned w = util_format_get_blockwidth(pf); const unsigned h = util_format_get_blockheight(pf); user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL); } info->screen = screen; info->target = PIPE_TEXTURE_2D; info->format = pf; info->width0 = Width; info->height0 = Height; info->depth0 = 1; if (Levels) info->last_level = Levels - 1; else info->last_level = util_logbase2(MAX2(Width, Height)); info->array_size = 1; info->nr_samples = 0; info->nr_storage_samples = 0; info->bind = PIPE_BIND_SAMPLER_VIEW; info->usage = PIPE_USAGE_DEFAULT; info->flags = 0; if (Usage & D3DUSAGE_RENDERTARGET) info->bind |= PIPE_BIND_RENDER_TARGET; if (Usage & D3DUSAGE_DEPTHSTENCIL) info->bind |= PIPE_BIND_DEPTH_STENCIL; if (Usage & D3DUSAGE_DYNAMIC) { info->usage = PIPE_USAGE_DYNAMIC; } if (Usage & D3DUSAGE_SOFTWAREPROCESSING) DBG("Application asked for Software Vertex Processing, " "but this is unimplemented\n"); if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */ user_buffer = (void *)*pSharedHandle; level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1)); (void) nine_format_get_size_and_offsets(pf, level_offsets, Width, Height, info->last_level); } else if (Pool != D3DPOOL_DEFAULT) { /* TODO: For D3DUSAGE_AUTOGENMIPMAP, it is likely we only have to * allocate only for the first level, since it is the only lockable * level. Check apps don't crash if we allocate smaller buffer (some * apps access sublevels of texture even if they locked only first * level) */ level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1)); user_buffer = align_calloc( nine_format_get_size_and_offsets(pf, level_offsets, Width, Height, info->last_level), 32); This->managed_buffer = user_buffer; if (!This->managed_buffer) return E_OUTOFMEMORY; } This->surfaces = CALLOC(info->last_level + 1, sizeof(*This->surfaces)); if (!This->surfaces) return E_OUTOFMEMORY; hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_TEXTURE, Format, Pool, Usage); if (FAILED(hr)) return hr; This->base.pstype = (Height == 1) ? 1 : 0; /* Create all the surfaces right away. * They manage backing storage, and transfers (LockRect) are deferred * to them. */ sfdesc.Format = Format; sfdesc.Type = D3DRTYPE_SURFACE; sfdesc.Usage = Usage; sfdesc.Pool = Pool; sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE; sfdesc.MultiSampleQuality = 0; for (l = 0; l <= info->last_level; ++l) { sfdesc.Width = u_minify(Width, l); sfdesc.Height = u_minify(Height, l); /* Some apps expect the memory to be allocated in * continous blocks */ user_buffer_for_level = user_buffer ? user_buffer + level_offsets[l] : NULL; hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This), This->base.base.resource, user_buffer_for_level, D3DRTYPE_TEXTURE, l, 0, &sfdesc, &This->surfaces[l]); if (FAILED(hr)) return hr; } /* Textures start initially dirty */ This->dirty_rect.width = Width; This->dirty_rect.height = Height; This->dirty_rect.depth = 1; /* widht == 0 means empty, depth stays 1 */ if (pSharedHandle && !*pSharedHandle) {/* Pool == D3DPOOL_SYSTEMMEM */ *pSharedHandle = This->surfaces[0]->data; } return D3D_OK; }
static HRESULT NineCubeTexture9_ctor( struct NineCubeTexture9 *This, struct NineUnknownParams *pParams, UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, HANDLE *pSharedHandle ) { struct pipe_resource *info = &This->base.base.info; struct pipe_screen *screen = pParams->device->screen; enum pipe_format pf; unsigned i, l, f, offset, face_size = 0; unsigned *level_offsets = NULL; D3DSURFACE_DESC sfdesc; void *p; HRESULT hr; DBG("This=%p pParams=%p EdgeLength=%u Levels=%u Usage=%d " "Format=%d Pool=%d pSharedHandle=%p\n", This, pParams, EdgeLength, Levels, Usage, Format, Pool, pSharedHandle); user_assert(EdgeLength, D3DERR_INVALIDCALL); /* user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); */ user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */ user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) || (Pool != D3DPOOL_SYSTEMMEM && Levels <= 1), D3DERR_INVALIDCALL); if (Usage & D3DUSAGE_AUTOGENMIPMAP) Levels = 0; pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW, FALSE, Pool == D3DPOOL_SCRATCH); if (pf == PIPE_FORMAT_NONE) return D3DERR_INVALIDCALL; if (compressed_format(Format)) { const unsigned w = util_format_get_blockwidth(pf); const unsigned h = util_format_get_blockheight(pf); user_assert(!(EdgeLength % w) && !(EdgeLength % h), D3DERR_INVALIDCALL); } info->screen = pParams->device->screen; info->target = PIPE_TEXTURE_CUBE; info->format = pf; info->width0 = EdgeLength; info->height0 = EdgeLength; info->depth0 = 1; if (Levels) info->last_level = Levels - 1; else info->last_level = util_logbase2(EdgeLength); info->array_size = 6; info->nr_samples = 0; info->bind = PIPE_BIND_SAMPLER_VIEW; info->usage = PIPE_USAGE_DEFAULT; info->flags = 0; if (Usage & D3DUSAGE_RENDERTARGET) info->bind |= PIPE_BIND_RENDER_TARGET; if (Usage & D3DUSAGE_DEPTHSTENCIL) info->bind |= PIPE_BIND_DEPTH_STENCIL; if (Usage & D3DUSAGE_DYNAMIC) { info->usage = PIPE_USAGE_DYNAMIC; info->bind |= PIPE_BIND_TRANSFER_READ | PIPE_BIND_TRANSFER_WRITE; } if (Usage & D3DUSAGE_SOFTWAREPROCESSING) DBG("Application asked for Software Vertex Processing, " "but this is unimplemented\n"); if (Pool != D3DPOOL_DEFAULT) { level_offsets = alloca(sizeof(unsigned) * (info->last_level + 1)); face_size = nine_format_get_size_and_offsets(pf, level_offsets, EdgeLength, EdgeLength, info->last_level); This->managed_buffer = align_malloc(6 * face_size, 32); if (!This->managed_buffer) return E_OUTOFMEMORY; } This->surfaces = CALLOC(6 * (info->last_level + 1), sizeof(*This->surfaces)); if (!This->surfaces) return E_OUTOFMEMORY; hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_CUBETEXTURE, Format, Pool, Usage); if (FAILED(hr)) return hr; This->base.pstype = 2; /* Create all the surfaces right away. * They manage backing storage, and transfers (LockRect) are deferred * to them. */ sfdesc.Format = Format; sfdesc.Type = D3DRTYPE_SURFACE; sfdesc.Usage = Usage; sfdesc.Pool = Pool; sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE; sfdesc.MultiSampleQuality = 0; /* We allocate the memory for the surfaces as continous blocks. * This is the expected behaviour, however we haven't tested for * cube textures in which order the faces/levels should be in memory */ for (f = 0; f < 6; f++) { offset = f * face_size; for (l = 0; l <= info->last_level; l++) { sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, l); p = This->managed_buffer ? This->managed_buffer + offset + level_offsets[l] : NULL; hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This), This->base.base.resource, p, D3DRTYPE_CUBETEXTURE, l, f, &sfdesc, &This->surfaces[f + 6 * l]); if (FAILED(hr)) return hr; } } for (i = 0; i < 6; ++i) { /* Textures start initially dirty */ This->dirty_rect[i].width = EdgeLength; This->dirty_rect[i].height = EdgeLength; This->dirty_rect[i].depth = 1; } return D3D_OK; }
void texture::settings::apply(const texture &texture) const { save_binding_state save(texture); texture.pixel_unpack_settings().apply(); if (compressed_format(m_internal_format)) { int compressed_image_size = m_compressed_image_size; if (!compressed_image_size) { switch (m_internal_format) { case texture::internal_format::compressed_rgb_s3tc_dxt1: compressed_image_size = ((m_width + 2) / 3) * ((m_height + 2) / 3) * 6; break; case texture::internal_format::compressed_rgba_s3tc_dxt1: compressed_image_size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 8; break; case texture::internal_format::compressed_rgba_s3tc_dxt3: case texture::internal_format::compressed_rgba_s3tc_dxt5: compressed_image_size = ((m_width + 3) / 4) * ((m_height + 3) / 4) * 16; break; } } __glcheck glCompressedTexImage2D((GLenum)m_parent->get_target(), m_level, (GLint)m_internal_format, m_width, m_height, 0, compressed_image_size, m_pixels); } else { __glcheck glTexImage2D((GLenum)m_parent->get_target(), m_level, (GLint)m_internal_format, m_width, m_height, 0, (GLint)m_format, (GLint)m_type, m_pixels); } __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_LEVEL, m_max_level); if (m_pixels) { __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_GENERATE_MIPMAP, m_generate_mipmap ? GL_TRUE : GL_FALSE); } __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_S, (GLint)m_wrap_s); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_T, (GLint)m_wrap_t); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_WRAP_R, (GLint)m_wrap_r); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_COMPARE_MODE, (GLint)m_compare_mode); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_COMPARE_FUNC, (GLint)m_compare_func); __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MIN_LOD, m_max_lod); __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_LOD, m_min_lod); __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_LOD_BIAS, m_lod); __glcheck glTexParameterfv((GLenum)m_parent->get_target(), GL_TEXTURE_BORDER_COLOR, m_border_color.rgba); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MIN_FILTER, (GLint)m_min_filter); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_MAG_FILTER, (GLint)m_mag_filter); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_R, (GLint)m_swizzle_r); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_G, (GLint)m_swizzle_g); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_B, (GLint)m_swizzle_b); __glcheck glTexParameteri((GLenum)m_parent->get_target(), GL_TEXTURE_SWIZZLE_A, (GLint)m_swizzle_a); __glcheck glTexParameterf((GLenum)m_parent->get_target(), GL_TEXTURE_MAX_ANISOTROPY_EXT, m_aniso); }
HRESULT NINE_WINAPI NineVolume9_LockBox( struct NineVolume9 *This, D3DLOCKED_BOX *pLockedVolume, const D3DBOX *pBox, DWORD Flags ) { struct pipe_resource *resource = This->resource; struct pipe_box box; unsigned usage; DBG("This=%p(%p) pLockedVolume=%p pBox=%p[%u..%u,%u..%u,%u..%u] Flags=%s\n", This, This->base.container, pLockedVolume, pBox, pBox ? pBox->Left : 0, pBox ? pBox->Right : 0, pBox ? pBox->Top : 0, pBox ? pBox->Bottom : 0, pBox ? pBox->Front : 0, pBox ? pBox->Back : 0, nine_D3DLOCK_to_str(Flags)); /* check if it's already locked */ user_assert(This->lock_count == 0, D3DERR_INVALIDCALL); /* set pBits to NULL after lock_count check */ user_assert(pLockedVolume, E_POINTER); pLockedVolume->pBits = NULL; user_assert(This->desc.Pool != D3DPOOL_DEFAULT || (This->desc.Usage & D3DUSAGE_DYNAMIC), D3DERR_INVALIDCALL); user_assert(!((Flags & D3DLOCK_DISCARD) && (Flags & D3DLOCK_READONLY)), D3DERR_INVALIDCALL); if (pBox && compressed_format (This->desc.Format)) { /* For volume all pools are checked */ const unsigned w = util_format_get_blockwidth(This->info.format); const unsigned h = util_format_get_blockheight(This->info.format); user_assert((pBox->Left == 0 && pBox->Right == This->desc.Width && pBox->Top == 0 && pBox->Bottom == This->desc.Height) || (!(pBox->Left % w) && !(pBox->Right % w) && !(pBox->Top % h) && !(pBox->Bottom % h)), D3DERR_INVALIDCALL); } if (Flags & D3DLOCK_DISCARD) { usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE; } else { usage = (Flags & D3DLOCK_READONLY) ? PIPE_TRANSFER_READ : PIPE_TRANSFER_READ_WRITE; } if (Flags & D3DLOCK_DONOTWAIT) usage |= PIPE_TRANSFER_DONTBLOCK; if (pBox) { user_assert(pBox->Right > pBox->Left, D3DERR_INVALIDCALL); user_assert(pBox->Bottom > pBox->Top, D3DERR_INVALIDCALL); user_assert(pBox->Back > pBox->Front, D3DERR_INVALIDCALL); user_assert(pBox->Right <= This->desc.Width, D3DERR_INVALIDCALL); user_assert(pBox->Bottom <= This->desc.Height, D3DERR_INVALIDCALL); user_assert(pBox->Back <= This->desc.Depth, D3DERR_INVALIDCALL); d3dbox_to_pipe_box(&box, pBox); if (u_box_clip_2d(&box, &box, This->desc.Width, This->desc.Height) < 0) { DBG("Locked volume intersection empty.\n"); return D3DERR_INVALIDCALL; } } else { u_box_3d(0, 0, 0, This->desc.Width, This->desc.Height, This->desc.Depth, &box); } if (This->data_conversion) { /* For now we only have uncompressed formats here */ pLockedVolume->RowPitch = This->stride_conversion; pLockedVolume->SlicePitch = This->layer_stride_conversion; pLockedVolume->pBits = This->data_conversion + box.z * This->layer_stride_conversion + box.y * This->stride_conversion + util_format_get_stride(This->format_conversion, box.x); } else if (This->data) { pLockedVolume->RowPitch = This->stride; pLockedVolume->SlicePitch = This->layer_stride; pLockedVolume->pBits = NineVolume9_GetSystemMemPointer(This, box.x, box.y, box.z); } else { pLockedVolume->pBits = This->pipe->transfer_map(This->pipe, resource, This->level, usage, &box, &This->transfer); if (!This->transfer) { if (Flags & D3DLOCK_DONOTWAIT) return D3DERR_WASSTILLDRAWING; return D3DERR_DRIVERINTERNALERROR; } pLockedVolume->RowPitch = This->transfer->stride; pLockedVolume->SlicePitch = This->transfer->layer_stride; } if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) { NineVolume9_MarkContainerDirty(This); NineVolume9_AddDirtyRegion(This, &box); } ++This->lock_count; return D3D_OK; }