summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorPatrick Rudolph <[email protected]>2016-09-15 20:28:17 +0200
committerAxel Davy <[email protected]>2016-10-10 23:43:51 +0200
commitba0274c7d6c3b77a36bbe1b444f427b0c873e2f3 (patch)
tree5d3a503f6ca77d6fcd70387a560c2b5d6b49139b /src/gallium
parent1f65f67b21821c00ebd9f1aa9f9f0b417b0a9677 (diff)
st/nine: Allocate surface resources in surface ctor
Allocate resources in surface ctor. Allows to use statetracker internal memory accounting. Fix for issue #231. Signed-off-by: Patrick Rudolph <[email protected]> Signed-off-by: Axel Davy <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/state_trackers/nine/device9.c54
-rw-r--r--src/gallium/state_trackers/nine/surface9.c58
2 files changed, 44 insertions, 68 deletions
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 298af86e484..50565b876dd 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -1134,11 +1134,8 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
HANDLE *pSharedHandle)
{
struct NineSurface9 *surface;
- struct pipe_screen *screen = This->screen;
- struct pipe_resource *resource = NULL;
HRESULT hr;
D3DSURFACE_DESC desc;
- struct pipe_resource templ;
DBG("This=%p type=%u Pool=%s Width=%u Height=%u Format=%s MS=%u Quality=%u "
"Discard_or_Lockable=%i ppSurface=%p pSharedHandle=%p\n",
@@ -1152,31 +1149,6 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
user_assert(Width && Height, D3DERR_INVALIDCALL);
user_assert(Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL);
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.width0 = Width;
- templ.height0 = Height;
- templ.depth0 = 1;
- templ.array_size = 1;
- templ.last_level = 0;
- templ.nr_samples = (unsigned)MultiSample;
- templ.usage = PIPE_USAGE_DEFAULT;
- templ.flags = 0;
- templ.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */
- switch (type) {
- case 0: templ.bind |= PIPE_BIND_RENDER_TARGET; break;
- case 1: templ.bind = d3d9_get_pipe_depth_format_bindings(Format); break;
- default:
- assert(type == 2);
- break;
- }
- templ.format = d3d9_to_pipe_format_checked(screen, Format, templ.target,
- templ.nr_samples, templ.bind,
- FALSE, Pool == D3DPOOL_SCRATCH);
-
- if (templ.format == PIPE_FORMAT_NONE && Format != D3DFMT_NULL)
- return D3DERR_INVALIDCALL;
-
desc.Format = Format;
desc.Type = D3DRTYPE_SURFACE;
desc.Usage = 0;
@@ -1188,31 +1160,17 @@ create_zs_or_rt_surface(struct NineDevice9 *This,
switch (type) {
case 0: desc.Usage = D3DUSAGE_RENDERTARGET; break;
case 1: desc.Usage = D3DUSAGE_DEPTHSTENCIL; break;
- default: break;
+ default: assert(type == 2); break;
}
- if (compressed_format(Format)) {
- const unsigned w = util_format_get_blockwidth(templ.format);
- const unsigned h = util_format_get_blockheight(templ.format);
+ hr = NineSurface9_new(This, NULL, NULL, NULL, 0, 0, 0, &desc, &surface);
+ if (SUCCEEDED(hr)) {
+ *ppSurface = (IDirect3DSurface9 *)surface;
- user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL);
+ if (surface->base.resource && Discard_or_Lockable && (type != 1))
+ surface->base.resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
}
- if (Pool == D3DPOOL_DEFAULT && Format != D3DFMT_NULL) {
- /* resource_create doesn't return an error code, so check format here */
- user_assert(templ.format != PIPE_FORMAT_NONE, D3DERR_INVALIDCALL);
- resource = screen->resource_create(screen, &templ);
- user_assert(resource, D3DERR_OUTOFVIDEOMEMORY);
- if (Discard_or_Lockable && (desc.Usage & D3DUSAGE_RENDERTARGET))
- resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
- } else {
- resource = NULL;
- }
- hr = NineSurface9_new(This, NULL, resource, NULL, 0, 0, 0, &desc, &surface);
- pipe_resource_reference(&resource, NULL);
-
- if (SUCCEEDED(hr))
- *ppSurface = (IDirect3DSurface9 *)surface;
return hr;
}
diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c
index 508fa9a508d..e6a48e2041b 100644
--- a/src/gallium/state_trackers/nine/surface9.c
+++ b/src/gallium/state_trackers/nine/surface9.c
@@ -57,30 +57,34 @@ NineSurface9_ctor( struct NineSurface9 *This,
union pipe_color_union rgba = {0};
struct pipe_surface *surf;
struct pipe_context *pipe = pParams->device->pipe;
+ bool allocate = !pContainer && pDesc->Format != D3DFMT_NULL;
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(pResource || (user_buffer && pDesc->Pool != D3DPOOL_DEFAULT) ||
- (!pContainer && pDesc->Pool != D3DPOOL_DEFAULT) ||
+ 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);
- /* The only way we can have !pContainer is being created
- * from create_zs_or_rt_surface with params 0 0 0 */
- assert(pContainer || (Level == 0 && Layer == 0 && TextureType == 0));
- /* Make sure no resource is passed for pool systemmem */
- assert(pDesc->Pool != D3DPOOL_SYSTEMMEM || !pResource);
+ 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;
+ /* 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;
@@ -90,7 +94,16 @@ NineSurface9_ctor( struct NineSurface9 *This,
This->base.info.array_size = 1;
This->base.info.nr_samples = pDesc->MultiSampleType;
This->base.info.usage = PIPE_USAGE_DEFAULT;
- This->base.info.bind = PIPE_BIND_SAMPLER_VIEW;
+ 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,
@@ -100,10 +113,16 @@ NineSurface9_ctor( struct NineSurface9 *This,
FALSE,
pDesc->Pool == D3DPOOL_SCRATCH);
- if (pDesc->Usage & D3DUSAGE_RENDERTARGET)
- This->base.info.bind |= PIPE_BIND_RENDER_TARGET;
- if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL)
- This->base.info.bind |= PIPE_BIND_DEPTH_STENCIL;
+ 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,
@@ -125,8 +144,8 @@ NineSurface9_ctor( struct NineSurface9 *This,
pDesc->Width);
}
- /* Ram buffer with no parent. Has to allocate the resource itself */
- if (!pResource && !pContainer) {
+ 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_malloc(
nine_format_get_level_alloc_size(This->base.info.format,
@@ -137,11 +156,10 @@ NineSurface9_ctor( struct NineSurface9 *This,
return E_OUTOFMEMORY;
}
- if (pResource && (pDesc->Usage & D3DUSAGE_DYNAMIC))
- pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
+ hr = NineResource9_ctor(&This->base, pParams, pResource,
+ allocate && (pDesc->Pool == D3DPOOL_DEFAULT),
+ D3DRTYPE_SURFACE, pDesc->Pool, pDesc->Usage);
- hr = NineResource9_ctor(&This->base, pParams, pResource, FALSE, D3DRTYPE_SURFACE,
- pDesc->Pool, pDesc->Usage);
if (FAILED(hr))
return hr;
@@ -156,7 +174,7 @@ NineSurface9_ctor( struct NineSurface9 *This,
This->stride = nine_format_get_stride(This->base.info.format, pDesc->Width);
- if (pResource && NineSurface9_IsOffscreenPlain(This))
+ if (pDesc->Usage & D3DUSAGE_DYNAMIC)
pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
/* TODO: investigate what else exactly needs to be cleared */