WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
-HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT levels, WINED3DRESOURCETYPE resource_type,
- IWineD3DDeviceImpl *device, UINT size, DWORD usage, const struct GlPixelFormatDesc *format_desc,
- WINED3DPOOL pool, IUnknown *parent, const struct wined3d_parent_ops *parent_ops)
+HRESULT basetexture_init(IWineD3DBaseTextureImpl *texture, UINT layer_count, UINT level_count,
+ WINED3DRESOURCETYPE resource_type, IWineD3DDeviceImpl *device, UINT size, DWORD usage,
+ const struct wined3d_format_desc *format_desc, WINED3DPOOL pool, IUnknown *parent,
+ const struct wined3d_parent_ops *parent_ops)
{
HRESULT hr;
return hr;
}
- texture->baseTexture.levels = levels;
+ texture->baseTexture.sub_resources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ level_count * layer_count * sizeof(*texture->baseTexture.sub_resources));
+ if (!texture->baseTexture.sub_resources)
+ {
+ ERR("Failed to allocate sub-resource array.\n");
+ resource_cleanup((IWineD3DResource *)texture);
+ return E_OUTOFMEMORY;
+ }
+
+ texture->baseTexture.layer_count = layer_count;
+ texture->baseTexture.level_count = level_count;
texture->baseTexture.filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE;
texture->baseTexture.LOD = 0;
texture->baseTexture.texture_rgb.dirty = TRUE;
void basetexture_cleanup(IWineD3DBaseTexture *iface)
{
basetexture_unload(iface);
+ HeapFree(GetProcessHeap(), 0, ((IWineD3DBaseTextureImpl *)iface)->baseTexture.sub_resources);
resource_cleanup((IWineD3DResource *)iface);
}
+IWineD3DResourceImpl *basetexture_get_sub_resource(IWineD3DBaseTextureImpl *texture, UINT layer, UINT level)
+{
+ if (layer >= texture->baseTexture.layer_count)
+ {
+ WARN("layer %u >= layer_count %u.\n", layer, texture->baseTexture.layer_count);
+ return NULL;
+ }
+
+ if (level >= texture->baseTexture.level_count)
+ {
+ WARN("level %u >= level_count %u.\n", level, texture->baseTexture.level_count);
+ return NULL;
+ }
+
+ return texture->baseTexture.sub_resources[layer * texture->baseTexture.level_count + level];
+}
+
/* A GL context is provided by the caller */
static void gltexture_delete(struct gl_texture *tex)
{
if (This->baseTexture.texture_rgb.name || This->baseTexture.texture_srgb.name)
{
- context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ context = context_acquire(device, NULL);
}
if(This->baseTexture.texture_rgb.name) {
return 0;
}
- if(LODNew >= This->baseTexture.levels)
- LODNew = This->baseTexture.levels - 1;
+ if (LODNew >= This->baseTexture.level_count)
+ LODNew = This->baseTexture.level_count - 1;
if(This->baseTexture.LOD != LODNew) {
This->baseTexture.LOD = LODNew;
DWORD basetexture_get_level_count(IWineD3DBaseTexture *iface)
{
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
- TRACE("(%p) : returning %d\n", This, This->baseTexture.levels);
- return This->baseTexture.levels;
+ TRACE("iface %p, returning %u.\n", iface, This->baseTexture.level_count);
+ return This->baseTexture.level_count;
}
HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType)
* Or should we delay the applying until the texture is used for drawing? For now, apply
* immediately.
*/
- struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+ struct wined3d_context *context = context_acquire(device, NULL);
ENTER_GL();
glBindTexture(textureDimensions, This->baseTexture.texture_rgb.name);
gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = 0;
- gl_tex->states[WINED3DTEXSTA_ELEMENTINDEX] = 0;
- gl_tex->states[WINED3DTEXSTA_DMAPOFFSET] = 0;
- gl_tex->states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
IWineD3DBaseTexture_SetDirty(iface, TRUE);
isNewTexture = TRUE;
* relying on the partial GL_ARB_texture_non_power_of_two emulation with texture rectangles
* (ie, do not care for cond_np2 here, just look for GL_TEXTURE_RECTANGLE_ARB)
*/
- if(textureDimensions != GL_TEXTURE_RECTANGLE_ARB) {
- TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1);
- glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1);
- checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)");
+ if (textureDimensions != GL_TEXTURE_RECTANGLE_ARB)
+ {
+ TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", This->baseTexture.level_count - 1);
+ glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.level_count - 1);
+ checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.level_count)");
}
if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) {
/* Cubemaps are always set to clamp, regardless of the sampler state. */
glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
- if(!cond_np2) {
- if(gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
+ if (!cond_np2)
+ {
+ if (gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE)
glValue = This->baseTexture.LOD;
- } else if(gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
- glValue = This->baseTexture.levels - 1;
- } else if(gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD) {
+ else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.level_count)
+ glValue = This->baseTexture.level_count - 1;
+ else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < This->baseTexture.LOD)
/* baseTexture.LOD is already clamped in the setter */
glValue = This->baseTexture.LOD;
- } else {
+ else
glValue = gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL];
- }
+
/* Note that D3DSAMP_MAXMIPLEVEL specifies the biggest mipmap(default 0), while
* GL_TEXTURE_MAX_LEVEL specifies the smallest mimap used(default 1000).
* So D3DSAMP_MAXMIPLEVEL is the same as GL_TEXTURE_BASE_LEVEL.
}
gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = aniso;
}
+
+ if (!(This->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW)
+ != !gl_tex->states[WINED3DTEXSTA_SHADOW])
+ {
+ if (This->resource.format_desc->Flags & WINED3DFMT_FLAG_SHADOW)
+ {
+ glTexParameteri(textureDimensions, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
+ glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
+ checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB)");
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = TRUE;
+ }
+ else
+ {
+ glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE)");
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
+ }
+ }
}