Import Upstream version 22.1.7

This commit is contained in:
su-fang 2022-09-29 09:43:28 +08:00
commit 17869f7af5
214 changed files with 121102 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# compiled source#
*.o
*.a
*.exe
#
*.orig
*.rej

9
CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
if (NOT DEFINED RUN_TEST_SUITE)
option (RUN_TEST_SUITE "run test suite after install" ON)
endif (NOT DEFINED RUN_TEST_SUITE)
project(igfx_gmmumd)
add_subdirectory(Source/GmmLib)

75
LICENSE.md Executable file
View File

@ -0,0 +1,75 @@
MIT License
Copyright (c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Includes spdlog utility licensed under MIT
The MIT License (MIT)
Copyright (c) 2016 Gabi Melman.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Copyright 2008, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

113
README.rst Normal file
View File

@ -0,0 +1,113 @@
Intel(R) Graphics Memory Management Library
*******************************************
Introduction
=============
The Intel(R) Graphics Memory Management Library provides device specific and buffer
management for the Intel(R) Graphics Compute Runtime for OpenCL(TM) and the
Intel(R) Media Driver for VAAPI.
License
========
The Intel(R) Graphics Memory Management Library is distributed under the MIT
Open Source license.
You may obtain a copy of the License at:
https://opensource.org/licenses/MIT
Building
========
1) Get gmmlib repository
2) Change it to root directory
``$ cd gmmlib``
3) Make a build directory
``$ mkdir build && cd build``
4) Run the cmake command to prepare build files
``$ cmake [-DCMAKE_BUILD_TYPE= Release | Debug | ReleaseInternal] [-DARCH= 64 | 32] ..``
5) Build the project
``$ make -j"$(nproc)" (Also performs compile time ULT)``
Install
=======
``$ sudo make install``
This will install the following files (e.g. on Ubuntu):
| -- Install configuration: "Release"
| -- Installing: /usr/local/lib/libigdgmm.so.12.1.0
| -- Installing: /usr/local/lib/libigdgmm.so.12
|
Not a stand alone software component.
GmmLib is built as dynamic library for Intel media driver and Compute runtime for OpenCL
Supported Platforms
-------------------
Intel Atom and Core Processors supporting Gen8/Gen9/Gen10 graphics devices
BDW (Broadwell)
SKL (Skylake, Kaby Lake, Coffee Lake)
BXTx (BXT: Broxton, APL: Apollo Lake, GLK: Gemini Lake)
KBLx (KBL: Kaby Lake, CFL: Coffe Lake, WHL: Whiskey Lake, CML: Comet Lake, AML: Amber Lake)
CNL (Cannonlake)
ICL (Icelake)
TGLx (TGL: Tiger Lake, RKL: Rocket Lake)
ADLx (ADL-S: Alder Lake S, ADL-P: Alder Lake P, ADL-N: Alder Lake N)
XE_LP (DG1)
XE_HP (XE_HP_SDV)
XE_HPC (PVC: Ponte Vecchio)
XE_HPG (DG2, ACM: Alchemist)
Release Tags
============
Gmmlib Release tag versioning schema follows:
| Tag ``intel-gmmlib-<x>.<y>.<z>`` will be stable release series with the same API and ABI version with only bug fixes where,
| x = GMMLIB_API_MAJOR_VERSION + 10,
| y = GMMLIB_API_MINOR_VERSION,
| z = RELEASE NUMBER which is incremented as 0,1,2,...n for changes including new flag, bug fixes, etc.
|
| Example:
| For GMM library ``libigdgmm.so.12.0.0``,
| Tag = ``intel-gmmlib-22.0.0`` where,
| 22 = GMMLIB_API_MAJOR_VERSION + 10 = 12 + 10
| 0 = GMMLIB_API_MINOR_VERSION
| 0 = RELEASE NUMBER
|
On potential ABI break changes,
| Tag ``intel-gmmlib-<x>.<y>.<z>`` becomes ``intel-gmmlib-<x + 1>.0.0``
| i.e ``intel-gmmlib-22.5.3`` becomes ``intel-gmmlib-23.0.0``
Known Issues and Limitations
============================
Current Gmmlib support only limited to Linux
(*) Other names and brands may be claimed as property of others.
---------------------------------------------------------------

View File

@ -0,0 +1,365 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
/*
File Name: AssertTracer.cpp
Abstract:
These functions enables reporting asserts to system log in the debug
driver build.
Notes:
\*****************************************************************************/
#if defined( _WIN32 ) && (defined( _DEBUG ) || defined( _RELEASE_INTERNAL ))
#include "AssertTracer.h"
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
// Windows.h defines MemoryFence as _mm_mfence, but this conflicts with llvm::sys::MemoryFence
#undef MemoryFence
#include <stdio.h>
#include <stdlib.h>
#if defined( __GMM_KMD__ ) || defined( STATIC_DRIVER_MODEL )
#include"BufferedDbg.h"
#include "igdKrnlEtwMacros.h"
#endif //__GMM_KMD__ || STATIC_DRIVER_MODEL
#if _DEBUG
/*****************************************************************************\
Function:
ReportAsserts
Description:
Sends message to the system log.
Input:
const char *expr -
The expression passed to function.
const char *file -
The name of the file that is the origin of the expression.
const char *func -
The function from which call to this function was made.
const unsigned long line -
The line number from file, which caused this function call.
const char *msg -
Message passed to the system log.
Output:
void - None.
\*****************************************************************************/
void __stdcall ReportAssert(
const char *expr,
const char *file,
const char *func,
const unsigned long line,
const char *msg )
{
#if !defined( __GMM_KMD__ ) && !defined( STATIC_DRIVER_MODEL )//We are in UMD, use the UMD implementation
#if 0
HANDLE hEventLog = RegisterEventSourceA( NULL, "GFX Driver AssertTracer" );
char *wideMessage;
if ( hEventLog != NULL )
{
// Calculate length with hard coded max unsigned long length plus some safe space.
size_t length = strlen( expr ) + strlen( file ) + strlen( func ) + strlen( msg ) + 15;
// Checks against maximum string size for ReportEvent lpStrings parameter.
// Cuts string to the limit size.
uint32_t maxSizeReached = 0;
if ( length > 31839 )
{
length = 31839;
maxSizeReached = 1;
}
wideMessage = ( char * ) malloc( sizeof( char ) * length );
if( wideMessage != NULL )
{
// snprintf spec: "The resulting character string will be terminated with a null character"
_snprintf_s( wideMessage, length, length / sizeof( char ), "%s:%lu\n%s\n%s\n%s", file, line, expr, func, msg);
ReportEventA( hEventLog, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ( LPCSTR* ) &wideMessage, NULL );
free( wideMessage );
}
DeregisterEventSource( hEventLog );
}
#endif //!define( WINDOWS_MOBILE )
// Windows Mobile has no implementation. Reference the parameters to remove the unreference param warnings.
(void)expr;
(void)file;
(void)func;
(void)line;
(void)msg;
#else //We are in KMD, use the KMD implementation
BufDbgPrint("ASSERT_TRACE: %s::%s:%i : %s : %s\n", file, func, line, expr, msg);
#endif //!defined( __GMM_KMD__ ) && !defined( STATIC_DRIVER_MODEL )
}
#endif
/*****************************************************************************\
Function:
ReportAssertsETW
Description:
Sends message to the system log.
Input:
const unsigned long ComponentMask
Contains the component id for which raised assert (KMD, MINIPORT..)
const char *expr -
The expression passed to function.
const char *file -
The name of the file that is the origin of the expression.
const char *func -
The function from which call to this function was made.
const unsigned long line -
The line number from file, which caused this function call.
const char *msg -
Message passed to the system log.
Output:
void - None.
\*****************************************************************************/
void __stdcall ReportAssertETW( const unsigned short compId,
const unsigned long compMsk,
const char *expr,
const char *file,
const char *func,
const unsigned long line,
const char *msg)
{
#if !defined( __GMM_KMD__ ) && !defined( STATIC_DRIVER_MODEL ) //We are in UMD, use the UMD implementation
// TODO: Add UMD code for ETW here.
// Reference the parameters to remove the unreference param warnings.
(void)compId;
(void)compMsk;
(void)expr;
(void)file;
(void)func;
(void)line;
(void)msg;
#else //We are in KMD, use the KMD implementation
// Log event if ETW session is active
if (g_ulHDGraphics_SessionActive)
{
EtwAssertPrint(compId, compMsk, expr, file, func, line, msg);
}
#endif
}
#elif defined( __linux__ ) && defined( _RELEASE_INTERNAL ) && !defined( __ANDROID__ )
#include <algorithm>
#include <syslog.h>
#include <execinfo.h>
#include <string>
#include <cxxabi.h>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <fstream>
#define CALL_STACK_REPORT_SIZE 50 // maximal limit of call stack to be reported in case of assertion
#define MAX_FUNCTION_NAME_LENGTH 100 // no worries it can be extended (relocated by driver if needed)
#define MAX_SYSLOG_ENTRY_LENGTH 1000 // Syslog protocol recommends minimum entry length 1KB (ubuntu rsyslog message limit is about 2K)
void LogAssertion( const char *function_name, const char *file_name, unsigned int line_number, const char *expr )
{
std::string stack;
std::string part1;
std::string part2;
std::size_t pos;
void *buffer[CALL_STACK_REPORT_SIZE];
char *function_name_buffer = NULL;
int nframes; // numer of frames to be returned
char **strings;
int i;
int status;
size_t length;
const size_t stringLength = 4096;
std::string oclAppCmdLine;
nframes = backtrace( buffer, CALL_STACK_REPORT_SIZE );
strings = backtrace_symbols( buffer, nframes );
if( strings == NULL )
{
perror( "Getting backtrace symbols error:" );
nframes = 0;
}
else
{
// Get Commandline of process (in that case OCL app)
// from process info itself eg. /proc/self/cmdline
oclAppCmdLine.reserve( stringLength );
std::ifstream fileCmdline( "/proc/self/cmdline", std::ifstream::binary );
if( fileCmdline.is_open() )
{
oclAppCmdLine = std::string( std::istreambuf_iterator< char >( fileCmdline ), std::istreambuf_iterator< char >() );
if( oclAppCmdLine.size() > 0 )
{
// Trim last \0 character
oclAppCmdLine.resize( oclAppCmdLine.size() - 1 );
// Format of /proc/self/cmdline is that args are separated with '\0'
// so for nicer printing we replace zeros with spaces (without terminating 0)
std::replace( oclAppCmdLine.begin(), oclAppCmdLine.end(), '\0', ' ' );
}
else
{
fprintf( stderr, "Getting Commandline of OCL app error: Error reading /proc/self/cmdline\n" );
}
}
else
{
fprintf( stderr, "Getting Commandline of OCL app error:" );
}
}
// allocation by malloc is suggessted by documentation as abi function may do some relocation
function_name_buffer = ( char * )malloc( MAX_FUNCTION_NAME_LENGTH );
if( function_name_buffer == NULL )
{
// Not enough memory to get small allocation then do not print stack
nframes = 0;
}
else
{
length = MAX_FUNCTION_NAME_LENGTH;
memset( function_name_buffer, 0, length );
}
for( i = 0; i < nframes; ++i )
{
// Generate signature of given stack frame eg. #0 #1 etc...
std::stringstream framePromptBuilder;
framePromptBuilder << "#" << i << " ";
const std::string &framePrompt = framePromptBuilder.str();
// demangle name eg. split stack frame into two pieces
part1 = strings[i];
pos = part1.find( "(" );
if( pos != std::string::npos )
{
// For final level instead of binary print whole commandline
// if were able to get one
if( ( i == nframes - 1 ) && ( !oclAppCmdLine.empty() ) )
{
//..call stack's part1 contains "(" so we add it here manualy
stack.append( ( oclAppCmdLine.insert( 0, "COMMANDLINE(" ) ).c_str() );
}
else
{
// part1 contains everything before section to be demangled
part1 = part1.substr( 0, pos + 1 );
stack.append(framePrompt);
stack.append( part1 );
}
// part2 contains string to be demangled
part2 = strings[i];
part2 = part2.substr( pos + 1 );
pos = part2.find( "+" );
// Final level may not have any function (static functions are not exposed)
if( pos != std::string::npos )
{
part2 = part2.substr( 0, pos );
function_name_buffer = abi::__cxa_demangle( part2.c_str(), function_name_buffer, &length, &status );
// in case of error during demangling attach mangled name
if( status != 0 )
{
stack.append( part2 );
}
else
{
stack.append( function_name_buffer );
}
stack.append( "())" );
free( function_name_buffer );
function_name_buffer = NULL;
}
else
{
// if there was no function then attach ")"
stack.append( ")" );
}
}
else
{
if( ( i == nframes - 1 ) && ( !oclAppCmdLine.empty() ) )
{
stack.append( ( oclAppCmdLine.insert( 0, "COMMANDLINE(" ) ).c_str() );
stack.append( ")" );
}
else
{
stack.append(framePrompt);
stack.append( strings[i] );
}
}
stack.append( " " );
}
//Compose full message..
std::string fullMsg = "File: ";
std::string syslogEntry;
fullMsg += file_name;
fullMsg += " line: ";
std::stringstream lineStr;
lineStr << line_number;
fullMsg += lineStr.str();
fullMsg += " function: ";
fullMsg += function_name;
fullMsg += " expr: ";
fullMsg += expr;
fullMsg += " ";
fullMsg += stack.c_str();
// split it into chunks we can send
openlog( "OpenCL", LOG_PID, LOG_USER );
pos = 0;
int numberOfChunks = ( fullMsg.length() / MAX_SYSLOG_ENTRY_LENGTH ) + 1;
while( pos < fullMsg.length() )
{
syslogEntry = fullMsg.substr( pos, MAX_SYSLOG_ENTRY_LENGTH );
// Add chunk ID / part number and send to syslog
syslog( LOG_MAKEPRI( LOG_USER,
LOG_ERR ), "[%zd/%d]%s", ( pos / MAX_SYSLOG_ENTRY_LENGTH + 1 ), numberOfChunks,
syslogEntry.c_str() );
pos += MAX_SYSLOG_ENTRY_LENGTH;
}
closelog();
// backtrace_symbols allocates memory in a malloc like way sop it should be freed
free( strings );
strings = NULL;
}
#endif //defined( _WIN32 ) && defined( _DEBUG )

View File

@ -0,0 +1,115 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
/*
File Name: AssertTracer.h
Abstract:
These functions enables reporting asserts to system log in the debug
driver build.
Notes:
\*****************************************************************************/
#ifndef _ASSERT_TRACER_H_
#define _ASSERT_TRACER_H_
#if defined( _WIN32 ) && (defined( _DEBUG ) || defined(_RELEASE_INTERNAL))
#if !defined( __GMM_KMD__ ) && !defined( STATIC_DRIVER_MODEL ) && !defined( LHDM )
#include <windows.h>
// Windows.h defines MemoryFence as _mm_mfence, but this conflicts with llvm::sys::MemoryFence
#undef MemoryFence
#include <stdio.h>
#include <stdlib.h>
#endif
#undef REPORT_ASSERT_MSG
#define REPORT_ASSERT_MSG( expr, msg ) \
if ( !( expr ) ) \
{ \
ReportAssert( #expr, __FILE__, __FUNCTION__, __LINE__, #msg ); \
}
#undef REPORT_ASSERT
#define REPORT_ASSERT( expr ) \
if ( !( expr ) ) \
{ \
ReportAssert( #expr, __FILE__, __FUNCTION__, __LINE__, "" ); \
}
#undef REPORT_ASSERT_MSG_ETW
#define REPORT_ASSERT_MSG_ETW( compId, compMsk, expr, msg ) \
if (!(expr)) \
{ \
ReportAssertETW( compId, compMsk, #expr, __FILE__, __FUNCTION__, __LINE__, #msg ); \
}
#undef REPORT_ASSERT_ETW
#define REPORT_ASSERT_ETW( compId, compMsk, expr ) \
if (!(expr)) \
{ \
ReportAssertETW( compId, compMsk, #expr, __FILE__, __FUNCTION__, __LINE__, "" ); \
}
#ifdef __cplusplus
extern "C"
{
#endif
void __stdcall ReportAssert( const char *expr,
const char *file,
const char *func,
const unsigned long line,
const char *msg );
void __stdcall ReportAssertETW(const unsigned short compId,
const unsigned long compMsk,
const char *expr,
const char *file,
const char *func,
const unsigned long line,
const char *msg );
#ifdef __cplusplus
}
#endif
#elif defined( __linux__ ) && defined( _RELEASE_INTERNAL ) && !defined( __ANDROID__ )
// do while() is missing ";" at the end and this is intentional
// As invoking assert looks like this: assert(expr); So semicolon will
// be stuck to do.. while() and that way sorting out possible
// problems when assert is used as block in one liner conditions
#define REPORT_ASSERT( expr ) \
do { \
if( !( expr ) ) \
{ \
LogAssertion( __FUNCTION__, __FILE__, __LINE__, #expr ); \
} \
} while( 0 )
#define REPORT_ASSERT_MSG( expr, msg ) REPORT_ASSERT( expr )
#define REPORT_ASSERT_ETW( CompId, compMsk, expr)
void LogAssertion( const char *function_name, const char *file_name, unsigned int line_number, const char *expr );
#else
#define REPORT_ASSERT_MSG( expr, msg )
#define REPORT_ASSERT( expr )
#define REPORT_ASSERT_MSG_ETW( compMsk, expr, msg )
#define REPORT_ASSERT_ETW( CompId, compMsk, expr )
#endif // defined( _WIN32 ) && defined( _DEBUG )
#endif //_ASSERT_TRACER_H_

View File

@ -0,0 +1,645 @@
# Copyright(c) 2017 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files(the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and / or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
cmake_minimum_required(VERSION 3.5)
project(igfx_gmmumd)
# GmmLib Api Version used for so naming
set(GMMLIB_API_MAJOR_VERSION 12)
set(GMMLIB_API_MINOR_VERSION 1)
if(NOT DEFINED MAJOR_VERSION)
set(MAJOR_VERSION 12)
endif()
if(NOT DEFINED MINOR_VERSION)
set(MINOR_VERSION 1)
endif()
if(NOT DEFINED PATCH_VERSION)
set(PATCH_VERSION 0)
endif()
if(NOT DEFINED GMMLIB_API_PATCH_VERSION)
set(GMMLIB_API_PATCH_VERSION ${PATCH_VERSION})
endif()
# The Gmmlib dll is generated as libigdgmm.so.<x>.<y>.<z> where,
# <x> = GMMLIB_API_MAJOR_VERSION
# <y> = GMMLIB_API_MINOR_VERSION
# <z> = GMMLIB_API_PATCH_VERSION
#
# Example: libigdgmm.so.12.0.0
# 12 = GMMLIB_API_MAJOR_VERSION
# 0 = GMMLIB_API_MINOR_VERSION
# 0 = GMMLIB_API_PATCH_VERSION
#
# Library version update
# - increment major for any ABI change
# - increment minor for any interface change (e.g. new/modified function)
#
# Example:
# On potential ABI break changes
#
# libigdgmm.so.<GMMLIB_API_MAJOR_VERSION>.y.z becomes libigdgmm.so.<GMMLIB_API_MAJOR_VERSION + 1>.0.0
# i.e libigdgmm.so.12.5.0 becomes libigdgmm.so.13.0.0
message(STATUS "API version: ${GMMLIB_API_MAJOR_VERSION}.${GMMLIB_API_MINOR_VERSION}.${GMMLIB_API_PATCH_VERSION}")
message(STATUS "Package version: ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}")
if(NOT DEFINED BS_USE_OSDM_BUILD_SYSTEM)
if(DEFINED ENV{BS_USE_OSDM_BUILD_SYSTEM})
set(BS_USE_OSDM_BUILD_SYSTEM "$ENV{BS_USE_OSDM_BUILD_SYSTEM}")
else()
set(BS_USE_OSDM_BUILD_SYSTEM FALSE)
endif()
endif()
# begin -- label bldsys file prologue
# WARNING: The "project" statement triggers reading of CMAKE_TOOLCHAIN_FILE
# and so must precede the inclusion below of bs_init.cmake .
function(bs_find_build_system gfx_dev_dir build_sys_dir build_sys_inc)
# If we are not building as a standalone project
if(DEFINED GFX_DEVELOPMENT_DIR)
set(_bs_gfx_development_dir "${GFX_DEVELOPMENT_DIR}")
elseif(DEFINED ENV{GFX_DEVELOPMENT_DIR})
set(_bs_gfx_development_dir "$ENV{GFX_DEVELOPMENT_DIR}")
else()
get_filename_component(_bs_cur_cmake_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_bs_parent_dir "${_bs_cur_cmake_dir}" DIRECTORY)
set(_bs_gfx_dir_found false)
while(NOT _bs_gfx_dir_found)
set(_bs_bldsys_dir "${_bs_parent_dir}/Tools/bldsys")
if(EXISTS ${_bs_bldsys_dir})
set(_bs_gfx_development_dir ${_bs_parent_dir})
set(_bs_gfx_dir_found true)
break()
endif()
get_filename_component(_bs_parent_dir "${_bs_parent_dir}" DIRECTORY)
if(${_bs_parent_dir} STREQUAL "/")
break()
endif()
endwhile(NOT _bs_gfx_dir_found)
if (NOT _bs_gfx_development_dir)
message(FATAL_ERROR "GFX_DEVELOPMENT_DIR not found (${_bs_gfx_development_dir}) - exiting!")
exit(1)
endif()
endif()
set(${gfx_dev_dir} "${_bs_gfx_development_dir}" PARENT_SCOPE)
set(${build_sys_dir} "${_bs_gfx_development_dir}/Tools/bldsys" PARENT_SCOPE)
set(${build_sys_inc} "${_bs_gfx_development_dir}/Tools/bldsys/include" PARENT_SCOPE)
endfunction(bs_find_build_system)
bs_find_build_system(GFX_DEVELOPMENT_DIR BUILD_SYS_DIR BUILD_SYS_INC)
include(${BUILD_SYS_DIR}/bs_init.cmake)
include(${BUILD_SYS_INC}/bs_dir_names.cmake)
# file prologue done
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
################################################################################
# Define GMM_DLL Target
################################################################################
set (GMM_LIB_DLL_NAME igfx_gmmumd_dll)
macro(GmmLibSetTargetConfig libTarget)
if (TARGET ${libTarget})
set_property(TARGET ${libTarget} APPEND PROPERTY COMPILE_DEFINITIONS
$<$<CONFIG:Release>: _RELEASE>
$<$<CONFIG:ReleaseInternal>: _RELEASE_INTERNAL>
$<$<CONFIG:Debug>: _DEBUG>
)
endif()
endmacro()
if(CMAKE_CONFIGURATION_TYPES)
set( CMAKE_CONFIGURATION_TYPES
"Debug"
"Release"
"ReleaseInternal")
set( CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Reset the configurations to what we need"
FORCE)
else()
if("${BUILD_TYPE}" STREQUAL "release")
set(CMAKE_BUILD_TYPE "Release")
elseif("${BUILD_TYPE}" STREQUAL "release-internal")
set(CMAKE_BUILD_TYPE "ReleaseInternal")
elseif("${BUILD_TYPE}" STREQUAL "debug")
set(CMAKE_BUILD_TYPE "Debug")
elseif("${BUILD_TYPE}" STREQUAL "RelWithDebInfo")
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
elseif("${BUILD_TYPE}" STREQUAL "MinSizeRel")
set(CMAKE_BUILD_TYPE "MinSizeRel")
endif()
endif()
set(GMMLIB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set (GMMLIB_ARCH "64")
else()
set (GMMLIB_ARCH "32")
endif()
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^aarch")
set(GMMLIB_MARCH "armv8-a+fp+simd")
elseif("${GMMLIB_MARCH}" STREQUAL "")
set(GMMLIB_MARCH "corei7")
endif()
MESSAGE("platform: ${CMAKE_HOST_SYSTEM_NAME}")
MESSAGE("source_dir: ${BS_DIR_GMMLIB}")
MESSAGE("arch: ${GMMLIB_ARCH}")
MESSAGE("build type: ${CMAKE_BUILD_TYPE}")
MESSAGE("SourceConfiguration:")
MESSAGE("CommonDir: ${BS_DIR_COMMON}")
MESSAGE("IncDir: ${BS_DIR_INC}")
# If '-DGMM_DYNAMIC_MOCS_TABLE=TRUE' (default is FALSE) passed to cmake
# configure command gmmlib will generate MOCS table dynamically depending on
# usage requests (Gen9). In this case on Linux user responsibility is to
# make sure that generated MOCS table is programmed on KMD level.
if (GMM_DYNAMIC_MOCS_TABLE)
MESSAGE("MOCS table: Dynamic")
add_definitions(-DGMM_DYNAMIC_MOCS_TABLE)
else()
MESSAGE("MOCS table: Static")
endif()
if(DEFINED UFO_DRIVER_OPTIMIZATION_LEVEL)
if(${UFO_DRIVER_OPTIMIZATION_LEVEL} GREATER 0)
add_definitions(-DGMM_GFX_GEN=${GFXGEN})
endif()
endif()
set(HEADERS_
${BS_DIR_GMMLIB}/CachePolicy/GmmCachePolicyConditionals.h
${BS_DIR_GMMLIB}/CachePolicy/GmmCachePolicyResourceUsageDefinitions.h
${BS_DIR_GMMLIB}/CachePolicy/GmmCachePolicyUndefineConditionals.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen10CachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen11CachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen12CachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen12dGPUCachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen8CachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen9CachePolicy.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen10.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen11.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen12.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen12dGPU.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen8.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen9.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmCachePolicy.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmCachePolicyCommon.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmCachePolicyExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmCommonExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmConst.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmDebug.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmFormatTable.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmHw.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmInfo.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmInfoExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmInternal.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmMemAllocator.hpp
${BS_DIR_GMMLIB}/inc/External/Common/GmmPlatformExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmProto.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmResourceFlags.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmResourceInfo.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmResourceInfoCommon.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmResourceInfoExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmTextureExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmUtil.h
${BS_DIR_GMMLIB}/inc/External/Linux/GmmResourceInfoLin.h
${BS_DIR_GMMLIB}/inc/External/Linux/GmmResourceInfoLinExt.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen10Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen11Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen12Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen8Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen9Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen10TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen11TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen12TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen7TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen8TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen9TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmTextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/GmmCommonInt.h
${BS_DIR_GMMLIB}/inc/Internal/Common/GmmLibInc.h
${BS_DIR_GMMLIB}/inc/GmmLib.h
${BS_DIR_GMMLIB}/inc/Internal/Common/GmmLogger.h
)
set(UMD_HEADERS
${HEADERS_}
${BS_DIR_GMMLIB}/inc/External/Common/GmmPageTableMgr.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmClientContext.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmLibDll.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmLibDllName.h
)
set(SOURCES_
${BS_DIR_COMMON}/AssertTracer/AssertTracer.cpp
${BS_DIR_GMMLIB}/CachePolicy/GmmCachePolicy.cpp
${BS_DIR_GMMLIB}/CachePolicy/GmmCachePolicyCommon.cpp
${BS_DIR_GMMLIB}/CachePolicy/GmmGen8CachePolicy.cpp
${BS_DIR_GMMLIB}/CachePolicy/GmmGen9CachePolicy.cpp
${BS_DIR_GMMLIB}/CachePolicy/GmmGen10CachePolicy.cpp
${BS_DIR_GMMLIB}/CachePolicy/GmmGen11CachePolicy.cpp
${BS_DIR_GMMLIB}/CachePolicy/GmmGen12CachePolicy.cpp
${BS_DIR_GMMLIB}/CachePolicy/GmmGen12dGPUCachePolicy.cpp
${BS_DIR_GMMLIB}/Platform/GmmGen11Platform.cpp
${BS_DIR_GMMLIB}/Platform/GmmGen12Platform.cpp
${BS_DIR_GMMLIB}/Platform/GmmGen8Platform.cpp
${BS_DIR_GMMLIB}/Platform/GmmGen9Platform.cpp
${BS_DIR_GMMLIB}/Platform/GmmGen10Platform.cpp
${BS_DIR_GMMLIB}/Platform/GmmPlatform.cpp
${BS_DIR_GMMLIB}/Resource/GmmResourceInfo.cpp
${BS_DIR_GMMLIB}/Resource/GmmResourceInfoCommon.cpp
${BS_DIR_GMMLIB}/Resource/GmmResourceInfoCommonEx.cpp
${BS_DIR_GMMLIB}/Resource/GmmRestrictions.cpp
${BS_DIR_GMMLIB}/Resource/Linux/GmmResourceInfoLinCWrapper.cpp
${BS_DIR_GMMLIB}/Texture/GmmGen7Texture.cpp
${BS_DIR_GMMLIB}/Texture/GmmGen8Texture.cpp
${BS_DIR_GMMLIB}/Texture/GmmGen9Texture.cpp
${BS_DIR_GMMLIB}/Texture/GmmGen10Texture.cpp
${BS_DIR_GMMLIB}/Texture/GmmGen11Texture.cpp
${BS_DIR_GMMLIB}/Texture/GmmGen12Texture.cpp
${BS_DIR_GMMLIB}/Texture/GmmTexture.cpp
${BS_DIR_GMMLIB}/Texture/GmmTextureAlloc.cpp
${BS_DIR_GMMLIB}/Texture/GmmTextureSpecialCases.cpp
${BS_DIR_GMMLIB}/Texture/GmmTextureOffset.cpp
${BS_DIR_GMMLIB}/GlobalInfo/GmmInfo.cpp
${BS_DIR_GMMLIB}/Utility/CpuSwizzleBlt/CpuSwizzleBlt.c
${BS_DIR_GMMLIB}/Utility/GmmLog/GmmLog.cpp
${BS_DIR_GMMLIB}/Utility/GmmUtility.cpp
)
set(UMD_SOURCES
${SOURCES_}
${BS_DIR_GMMLIB}/TranslationTable/GmmAuxTable.cpp
${BS_DIR_GMMLIB}/TranslationTable/GmmPageTableMgr.cpp
${BS_DIR_GMMLIB}/TranslationTable/GmmUmdTranslationTable.cpp
${BS_DIR_GMMLIB}/GlobalInfo/GmmClientContext.cpp
${BS_DIR_GMMLIB}/GlobalInfo/GmmLibDllMain.cpp
)
source_group("Source Files\\Cache Policy\\Client Files" FILES
${BS_DIR_GMMLIB}/CachePolicy/GmmCachePolicyResourceUsageDefinitions.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen10CachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen11CachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen12CachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen12dGPUCachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen8CachePolicy.h
${BS_DIR_GMMLIB}/CachePolicy/GmmGen9CachePolicy.h
)
source_group("Source Files\\Cache Policy" ${BS_DIR_GMMLIB}/CachePolicy/*.cpp)
source_group("Source Files\\Global" ${BS_DIR_GMMLIB}/GlobalInfo/.*)
source_group("Source Files\\Platform" ${BS_DIR_GMMLIB}/Platform/.*)
source_group("Source Files\\Texture" ${BS_DIR_GMMLIB}/Texture/.*)
source_group("Source Files\\Translation Table" ${BS_DIR_GMMLIB}/TranslationTable/.*)
source_group("Source Files\\Utility" ${BS_DIR_GMMLIB}/Utility/.*)
source_group("Source Files\\Resource" FILES
${BS_DIR_GMMLIB}/Resource/GmmResourceInfo.cpp
${BS_DIR_GMMLIB}/Resource/GmmResourceInfoCommon.cpp
${BS_DIR_GMMLIB}/Resource/GmmResourceInfoCommonEx.cpp
${BS_DIR_GMMLIB}/Resource/GmmRestrictions.cpp)
source_group("Source Files\\Resource\\Linux" FILES
${BS_DIR_GMMLIB}/Resource/Linux/GmmResourceInfoLinCWrapper.cpp
)
source_group("Source Files\\TranslationTable\\Windows" FILES
${BS_DIR_GMMLIB}/TranslationTable/GmmAuxTable.cpp
${BS_DIR_GMMLIB}/TranslationTable/GmmPageTableMgr.cpp
${BS_DIR_GMMLIB}/TranslationTable/GmmUmdTranslationTable.cpp)
source_group("Source Files\\TranslationTable" FILES
${BS_DIR_GMMLIB}/TranslationTable/GmmUmdTranslationTable.h)
source_group("Header Files\\External\\Common" FILES
${BS_DIR_GMMLIB}/inc/External/Common/GmmCachePolicy.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmCachePolicyCommon.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmCachePolicyExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmCommonExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmConst.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmDebug.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmFormatTable.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmHw.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmInfo.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmInfoExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmInternal.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmMemAllocator.hpp
${BS_DIR_GMMLIB}/inc/External/Common/GmmPageTableMgr.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmPlatformExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmResourceFlags.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmResourceInfo.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmResourceInfoCommon.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmResourceInfoExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmTextureExt.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmUtil.h
${BS_DIR_GMMLIB}/inc/External/Common/GmmClientContext.h
)
source_group("Header Files" FILES
${BS_DIR_GMMLIB}/inc/GmmLib.h
)
source_group("Header Files\\External\\Common\\Cache Policy" FILES
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen10.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen11.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen12.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen12dGPU.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen8.h
${BS_DIR_GMMLIB}/inc/External/Common/CachePolicy/GmmCachePolicyGen9.h
)
source_group("Header Files\\External\\Linux" FILES
${BS_DIR_GMMLIB}/inc/External/Linux/GmmResourceInfoLin.h
${BS_DIR_GMMLIB}/inc/External/Linux/GmmResourceInfoLinExt.h
)
source_group("Header Files\\Internal\\Common" FILES
${BS_DIR_GMMLIB}/inc/Internal/Common/GmmLibInc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/GmmProto.h
)
source_group("Header Files\\Internal\\Common\\Platform" FILES
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen10Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen11Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen12Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen8Platform.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Platform/GmmGen9Platform.h
)
source_group("Header Files\\Internal\\Common\\Texture" FILES
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen10TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen11TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen12TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen7TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen8TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmGen9TextureCalc.h
${BS_DIR_GMMLIB}/inc/Internal/Common/Texture/GmmTextureCalc.h
)
include_directories(BEFORE ${BS_DIR_GMMLIB}/)
include_directories(BEFORE ${PROJECT_SOURCE_DIR})
include_directories(
${BS_DIR_GMMLIB}
${BS_DIR_GMMLIB}/Utility/GmmLog
${BS_DIR_GMMLIB}/inc
${BS_DIR_GMMLIB}/Utility
${BS_DIR_GMMLIB}/GlobalInfo
${BS_DIR_GMMLIB}/Texture
${BS_DIR_GMMLIB}/Resource
${BS_DIR_GMMLIB}/Platform
${BS_DIR_UTIL}
${BS_DIR_INC}
${BS_DIR_INC}/common
${BS_DIR_INC}/umKmInc
${BS_DIR_INSTALL}
#${BS_DIR_ANDROID}/include
)
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^aarch")
include_directories(${GFX_DEVELOPMENT_DIR}/third_party/sse2neon)
endif()
set(headers
${HEADERS_}
)
set(SOURCES
${SOURCES_}
)
# set compiler options
include(Linux.cmake)
###################################################################################
# create dll library
###################################################################################
add_library( ${GMM_LIB_DLL_NAME} SHARED igdgmm.rc ${UMD_SOURCES} ${UMD_HEADERS})
if(MSVC)
set_target_properties(${GMM_LIB_DLL_NAME} PROPERTIES OUTPUT_NAME "igdgmm${GMMLIB_ARCH}")
bs_set_wdk(${GMM_LIB_DLL_NAME})
GmmLibSetTargetConfig( ${GMM_LIB_DLL_NAME} )
set_target_properties(${GMM_LIB_DLL_NAME} PROPERTIES VS_GLOBAL_DriverTargetPlatform Universal)
set_target_properties(${GMM_LIB_DLL_NAME} PROPERTIES VS_PLATFORM_TOOLSET WindowsApplicationForDrivers10.0)
windows_umd_props_universal(${GMM_LIB_DLL_NAME})
target_link_libraries( ${GMM_LIB_DLL_NAME}
onecoreuap.lib
)
else()
set_target_properties(${GMM_LIB_DLL_NAME} PROPERTIES OUTPUT_NAME "igdgmm")
set_target_properties(${GMM_LIB_DLL_NAME} PROPERTIES VERSION ${GMMLIB_API_MAJOR_VERSION}.${GMMLIB_API_MINOR_VERSION}.${GMMLIB_API_PATCH_VERSION})
set_target_properties(${GMM_LIB_DLL_NAME} PROPERTIES SOVERSION ${GMMLIB_API_MAJOR_VERSION})
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${GMM_LIB_DLL_NAME} Threads::Threads)
endif()
###################################################################################
# End of DLL create library
###################################################################################
bs_set_defines()
bs_set_force_exceptions()
bs_set_post_target()
###################################################################################
# Set common macros for DLL
###################################################################################
bs_set_extra_target_properties(${GMM_LIB_DLL_NAME}
_ATL_NO_WIN_SUPPORT
SMALL_POOL_ALLOC
__GMM
__GFX_MACRO_C__
UNUSED_ISTDLIB_MT
__UMD
GMM_UNIFY_DAF_API
)
if(CMAKE_BUILD_TYPE STREQUAL "ReleaseInternal")
bs_set_extra_target_properties(${GMM_LIB_DLL_NAME} _RELEASE_INTERNAL)
endif()
target_include_directories(${GMM_LIB_DLL_NAME} INTERFACE
${BS_DIR_GMMLIB}/inc
${BS_DIR_INC}
${BS_DIR_INC}/common)
###################################################################################
# End of Set macros DLL
###################################################################################
bs_set_extra_target_properties(${GMM_LIB_DLL_NAME}
ISTDLIB_UMD
UNUSED_ISTDLIB_MT
GMM_UNIFIED_LIB
GMM_LIB_DLL
GMM_LIB_DLL_EXPORTS
)
if("${GMMLIB_ARCH}" MATCHES "64")
bs_set_extra_target_properties(${GMM_LIB_DLL_NAME}
_X64)
endif()
if(NOT DEFINED RUN_TEST_SUITE OR RUN_TEST_SUITE)
add_subdirectory(ULT)
endif()
set (GMM_UMD_DLL "igdgmm")
include(os_release_info.cmake)
get_os_release_info(os_name os_version)
if("${os_name}" STREQUAL "clear-linux-os")
# clear-linux-os distribution avoids /etc for distribution defaults.
# Set this variable explicitly before including GNUInstallDirs.
set(CMAKE_INSTALL_SYSCONFDIR "usr/share/defaults/etc")
endif()
if(UNIX)
include(GNUInstallDirs)
configure_file(${BS_DIR_GMMLIB}/igdgmm.h.in ${CMAKE_BINARY_DIR}/igdgmm.h)
configure_file(${BS_DIR_GMMLIB}/igdgmm.pc.in ${CMAKE_BINARY_DIR}/igdgmm.pc @ONLY)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/postinst "/sbin/ldconfig\n")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp/postrm "/sbin/ldconfig\n")
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/postinst DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/postrm DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(TARGETS ${GMM_LIB_DLL_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT gmmlib NAMELINK_SKIP)
install(TARGETS ${GMM_LIB_DLL_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT gmmlib-devel NAMELINK_ONLY)
install(DIRECTORY ${BS_DIR_GMMLIB} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/igdgmm COMPONENT gmmlib-devel
FILES_MATCHING PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "Internal" EXCLUDE
PATTERN "ULT" EXCLUDE
PATTERN "spdlog" EXCLUDE)
install (DIRECTORY ${BS_DIR_INC} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/igdgmm COMPONENT gmmlib-devel
FILES_MATCHING PATTERN "*.h"
PATTERN "*.hpp")
install (DIRECTORY ${BS_DIR_UTIL} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/igdgmm COMPONENT gmmlib-devel
FILES_MATCHING PATTERN "*.h"
PATTERN "*.hpp")
install (FILES ${BS_DIR_GMMLIB}/Utility/CpuSwizzleBlt/CpuSwizzleBlt.c
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/igdgmm/GmmLib/Utility/CpuSwizzleBlt/ COMPONENT gmmlib-devel)
install(FILES ${CMAKE_BINARY_DIR}/igdgmm.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT gmmlib-devel)
install(FILES ${CMAKE_BINARY_DIR}/igdgmm.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/igdgmm COMPONENT gmmlib-devel)
if(GMMLIB_CPACK_GENERATOR)
set(CPACK_GENERATOR "${GMMLIB_CPACK_GENERATOR}")
else()
# If generators list was not define build native package for current distro
if(EXISTS "/etc/debian_version")
set(CPACK_GENERATOR "DEB")
elseif(EXISTS "/etc/redhat-release")
set(CPACK_GENERATOR "RPM")
else()
set(CPACK_GENERATOR "TXZ")
endif()
endif()
set(CPACK_PACKAGE_NAME "intel")
set(CPACK_PACKAGE_VENDOR "Intel Corporation")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Intel(R) Graphics Memory Management Library Package")
set(CPACK_PACKAGE_ARCHITECTURE "x86_64")
set(CPACK_PACKAGE_VERSION_MAJOR ${MAJOR_VERSION})
set(CPACK_PACKAGE_VERSION_MINOR ${MINOR_VERSION})
set(CPACK_PACKAGE_VERSION_PATCH ${PATCH_VERSION})
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${GMMLIB_INSTALL_TIME_ROOT_DIR})
set(CPACK_SET_DESTDIR TRUE)
set(CPACK_PACKAGE_RELOCATABLE FALSE)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Intel")
set(CPACK_DEBIAN_COMPRESSION_TYPE "xz")
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_BINARY_DIR}/postinst;${CMAKE_CURRENT_BINARY_DIR}/postrm")
set(CPACK_RPM_PACKAGE_ARCHITECTURE "x86_64")
set(CPACK_RPM_PACKAGE_RELEASE 1)
set(CPACK_RPM_COMPRESSION_TYPE "xz")
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/postinst")
set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/postrm")
if(CMAKE_VERSION VERSION_GREATER 3.6 OR CMAKE_VERSION VERSION_EQUAL 3.6)
set(CPACK_DEBIAN_GMMLIB_FILE_NAME "intel-gmmlib_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
set(CPACK_DEBIAN_GMMLIB-DEVEL_FILE_NAME "intel-gmmlib-devel_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb")
set(CPACK_RPM_GMMLIB_FILE_NAME "intel-gmmlib-${CPACK_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}%{?dist}.${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
set(CPACK_RPM_GMMLIB-DEVEL_FILE_NAME "intel-gmmlib-devel-${CPACK_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}%{?dist}.${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
set(CPACK_ARCHIVE_GMMLIB_FILE_NAME "intel-gmmlib-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_ARCHITECTURE}")
set(CPACK_ARCHIVE_GMMLIB-DEVEL_FILE_NAME "intel-gmmlib-devel-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_ARCHITECTURE}")
else()
if(CPACK_GENERATOR STREQUAL "DEB")
set(CPACK_PACKAGE_FILE_NAME "intel-gmmlib_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
elseif(CPACK_GENERATOR STREQUAL "RPM")
set(CPACK_PACKAGE_FILE_NAME "intel-gmmlib-${CPACK_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}%{?dist}.${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
else()
set(CPACK_PACKAGE_FILE_NAME "intel-gmmlib-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_ARCHITECTURE}")
endif()
endif()
set(CPACK_DEBIAN_GMMLIB-DEVEL_PACKAGE_DEPENDS "intel-gmmlib(=${CPACK_PACKAGE_VERSION})")
set(CPACK_RPM_GMMLIB-DEVEL_PACKAGE_REQUIRES "intel-gmmlib = ${CPACK_PACKAGE_VERSION}")
set(CPACK_COMPONENT_INSTALL ON)
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_RPM_COMPONENT_INSTALL ON)
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_COMPONENTS_ALL gmmlib gmmlib-devel)
include (CPack)
endif()

View File

@ -0,0 +1,177 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmCachePolicy.h"
/////////////////////////////////////////////////////////////////////////////////////
/// C Wrapper function for GmmLib::GmmCachePolicyGetPteType
/// @see GmmLib::GmmCachePolicyCommon::CachePolicyGetPteType()
//
/// @param[in] pLibContext: pGmmLibContext
/// @param[in] Usage: type of usage
///
/// @return GMM_PTE_CACHE_CONTROL_BITS:Populated PTE
///
/////////////////////////////////////////////////////////////////////////////////////
GMM_PTE_CACHE_CONTROL_BITS GMM_STDCALL GmmCachePolicyGetPteType(void *pLibContext, GMM_RESOURCE_USAGE_TYPE Usage)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
return pGmmLibContext->GetCachePolicyObj()->CachePolicyGetPteType(Usage);
}
/////////////////////////////////////////////////////////////////////////////////////
/// C Wrapper function for GmmLib::GmmCachePolicyIsUsagePTECached
/// @see GmmLib::GmmCachePolicyCommon::CachePolicyIsUsagePTECached()
///
/// @param[in] pLibContext: pGmmLibContext
/// @param[in] Usage: type of usage
///
/// @return 1 if the usage PTE entry is set for cached, 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmCachePolicyIsUsagePTECached(void *pLibContext, GMM_RESOURCE_USAGE_TYPE Usage)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
return pGmmLibContext->GetCachePolicyObj()->CachePolicyIsUsagePTECached(Usage);
}
/////////////////////////////////////////////////////////////////////////////////////
/// C Wrapper function to return L1 Cache Control on DG2 for a given resource type
///
/// @param[in] pLibContext: pGmmLibContext
/// @param[in] Usage: type of usage
///
/// @return Value of L1 Cache control.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmGetSurfaceStateL1CachePolicy(void *pLibContext, GMM_RESOURCE_USAGE_TYPE Usage)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
return pGmmLibContext->GetCachePolicyElement(Usage).L1CC;
}
/////////////////////////////////////////////////////////////////////////////////////
/// C wrapper for GmmLib::GmmResourceInfoCommon::GetCachePolicyUsage.
/// @see GmmLib::GmmResourceInfoCommon::GetCachePolicyUsage()
///
/// @param[in] pGmmResource: Pointer to the GmmResourceInfo class
/// @return Cache policy usage
/////////////////////////////////////////////////////////////////////////////////////
GMM_RESOURCE_USAGE_TYPE GMM_STDCALL GmmCachePolicyGetResourceUsage(GMM_RESOURCE_INFO *pResInfo)
{
__GMM_ASSERT(pResInfo);
return pResInfo->GetCachePolicyUsage();
}
/////////////////////////////////////////////////////////////////////////////////////
/// C wrapper for GmmLib::GmmResourceInfoCommon::OverrideCachePolicyUsage.
/// @see GmmLib::GmmResourceInfoCommon::OverrideCachePolicyUsage()
///
/// @param[in] pGmmResource: Pointer to the GmmResourceInfo class
/// @param[in] Cache policy usage
/////////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL GmmCachePolicyOverrideResourceUsage(GMM_RESOURCE_INFO *pResInfo, GMM_RESOURCE_USAGE_TYPE Usage)
{
pResInfo->OverrideCachePolicyUsage(Usage);
}
/////////////////////////////////////////////////////////////////////////////////////
/// C Wrapper function for GmmLib::GmmCachePolicyGetMemoryObject
/// @see GmmLib::GmmCachePolicyCommon::CachePolicyGetMemoryObject()
///
/// param[in] pResInfo: Resource info for resource, can be NULL.
/// param[in] Usage: Current usage for resource.
///
/// @return MEMORY_OBJECT_CONTROL_STATE: Gen adjusted MOCS structure (cache
/// policy) for the given buffer use.
/////////////////////////////////////////////////////////////////////////////////////
MEMORY_OBJECT_CONTROL_STATE GMM_STDCALL GmmCachePolicyGetMemoryObject(void *pLibContext, GMM_RESOURCE_INFO *pResInfo, GMM_RESOURCE_USAGE_TYPE Usage)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
return pGmmLibContext->GetCachePolicyObj()->CachePolicyGetMemoryObject(pResInfo, Usage);
}
/////////////////////////////////////////////////////////////////////////////////////
/// C Wrapper function for GmmLib::GmmCachePolicyGetOriginalMemoryObject
/// @see GmmLib::GmmCachePolicyCommon::CachePolicyGetOriginalMemoryObject()
///
/// @param[in] pResInfo: Resource info for resource , can be null
/// @param[in] Usage: Current usage for resource
///
/// @return MEMORY_OBJECT_CONTROL_STATE: Populated memory object
///
/////////////////////////////////////////////////////////////////////////////////////
MEMORY_OBJECT_CONTROL_STATE GMM_STDCALL GmmCachePolicyGetOriginalMemoryObject(void *pLibContext, GMM_RESOURCE_INFO *pResInfo)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
return pGmmLibContext->GetCachePolicyObj()->CachePolicyGetOriginalMemoryObject(pResInfo);
}
/////////////////////////////////////////////////////////////////////////////////////
/// C Wrapper function for GmmCachePolicy::GmmGetWantedMemoryType.
/// @see GmmLib::GmmCachePolicy::GetWantedMemoryType()
///
/// @param[in] pLibContext: pGmmLibContext
/// @param[in] CachePolicy:cache policy for a usage
///
/// @return wanted memory type
/////////////////////////////////////////////////////////////////////////////////////
GMM_GFX_MEMORY_TYPE GmmGetWantedMemoryType(void *pLibContext, GMM_CACHE_POLICY_ELEMENT CachePolicy)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
return pGmmLibContext->GetCachePolicyObj()->GetWantedMemoryType(CachePolicy);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns count of current MOCS values for MOCS Table programming at GMM boot
///
/// @param[in] pLibContext: pGmmLibContext
/// @return uint32_t no of mocs register required to program
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GMM_STDCALL GmmCachePolicyGetMaxMocsIndex(void *pLibContext)
{
GMM_LIB_CONTEXT * pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
GMM_CACHE_POLICY * pCachePolicy = pGmmLibContext->GetCachePolicyObj();
GmmLib::GmmGen9CachePolicy *ptr = static_cast<GmmLib::GmmGen9CachePolicy *>(pCachePolicy);
return ptr->CurrentMaxMocsIndex;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns count of current L1 HDC MOCS values for MOCS Table programming at GMM boot
///
/// @param[in] pLibContext: pGmmLibContext
/// @return uint32_t max L1 hdc mocs index needed to program
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GMM_STDCALL GmmCachePolicyGetMaxL1HdcMocsIndex(void *pLibContext)
{
GMM_LIB_CONTEXT * pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
GMM_CACHE_POLICY * pCachePolicy = pGmmLibContext->GetCachePolicyObj();
GmmLib::GmmGen9CachePolicy *ptr = static_cast<GmmLib::GmmGen9CachePolicy *>(pCachePolicy);
return ptr->CurrentMaxL1HdcMocsIndex;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns count of current Special MOCS values for MOCS Table programming at GMM boot
///
/// @param[in] pLibContext: pGmmLibContext
/// @return uint32_t max special mocs index needed to program
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GMM_STDCALL GmmCachePolicyGetMaxSpecialMocsIndex(void *pLibContext)
{
GMM_LIB_CONTEXT * pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
GMM_CACHE_POLICY *pCachePolicy = pGmmLibContext->GetCachePolicyObj();
return pCachePolicy->GetMaxSpecialMocsIndex();
}

View File

@ -0,0 +1,132 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmCachePolicy.h"
/////////////////////////////////////////////////////////////////////////////////////
/// Constructor for the GmmCachePolicyCommon Class, initializes the CachePolicy
/// @param[in] pCachePolicy
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::GmmCachePolicyCommon::GmmCachePolicyCommon(GMM_CACHE_POLICY_ELEMENT *pCachePolicy, Context *pGmmLibContext)
{
this->pCachePolicy = pCachePolicy;
this->pGmmLibContext = pGmmLibContext;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the wanted memory type for this usage.
///
/// @param[in] CachePolicy: cache policy for a usage
///
/// @return wanted memory type
/////////////////////////////////////////////////////////////////////////////////////
GMM_GFX_MEMORY_TYPE GmmLib::GmmCachePolicyCommon::GetWantedMemoryType(GMM_CACHE_POLICY_ELEMENT CachePolicy)
{
GMM_GFX_MEMORY_TYPE WantedMemoryType = GMM_GFX_UC_WITH_FENCE;
if(CachePolicy.WT)
{
WantedMemoryType = GMM_GFX_WT;
}
else if(!(CachePolicy.LLC || CachePolicy.ELLC))
{
WantedMemoryType = GMM_GFX_UC_WITH_FENCE;
}
else
{
WantedMemoryType = GMM_GFX_WB;
}
return WantedMemoryType;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Generates memory object based on resource usage
///
/// @param[in] pResInfo: Resource info for resource , can be null
/// @param[in] Usage: Current usage for resource
///
/// @return MEMORY_OBJECT_CONTROL_STATE: Populated memory object
///
/////////////////////////////////////////////////////////////////////////////////////
MEMORY_OBJECT_CONTROL_STATE GMM_STDCALL GmmLib::GmmCachePolicyCommon::CachePolicyGetOriginalMemoryObject(GMM_RESOURCE_INFO *pResInfo)
{
MEMORY_OBJECT_CONTROL_STATE MOCS = pGmmLibContext->GetCachePolicyElement(GMM_RESOURCE_USAGE_UNKNOWN).MemoryObjectOverride;
if(pResInfo)
{
MOCS = pResInfo->GetMOCS();
}
return MOCS;
}
/////////////////////////////////////////////////////////////////////////////////////
/// A simple getter function returning the MOCS (cache policy) for a given
/// use Usage of the named resource pResInfo.
/// Typically used to populate a SURFACE_STATE for a GPU task.
///
/// @param[in] pResInfo: Resource info for resource, can be NULL.
/// @param[in] Usage: Current usage for resource.
///
/// @return MEMORY_OBJECT_CONTROL_STATE: Gen adjusted MOCS structure (cache
/// policy) for the given buffer use.
/////////////////////////////////////////////////////////////////////////////////////
MEMORY_OBJECT_CONTROL_STATE GMM_STDCALL GmmLib::GmmCachePolicyCommon::CachePolicyGetMemoryObject(GMM_RESOURCE_INFO *pResInfo, GMM_RESOURCE_USAGE_TYPE Usage)
{
const GMM_CACHE_POLICY_ELEMENT *CachePolicy = NULL;
__GMM_ASSERT(pGmmLibContext->GetCachePolicyElement(Usage).Initialized);
CachePolicy = pGmmLibContext->GetCachePolicyUsage();
// Prevent wrong Usage for XAdapter resources. UMD does not call GetMemoryObject on shader resources but,
// when they add it someone could call it without knowing the restriction.
if(pResInfo &&
pResInfo->GetResFlags().Info.XAdapter &&
Usage != GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE)
{
__GMM_ASSERT(false);
}
if(!pResInfo ||
(CachePolicy[Usage].Override & CachePolicy[pResInfo->GetCachePolicyUsage()].IDCode) ||
(CachePolicy[Usage].Override == ALWAYS_OVERRIDE))
{
return CachePolicy[Usage].MemoryObjectOverride;
}
else
{
return CachePolicy[Usage].MemoryObjectNoOverride;
}
return CachePolicy[GMM_RESOURCE_USAGE_UNKNOWN].MemoryObjectOverride;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Generates PTE based on resource usage
///
/// @param[in] Usage: type of usage
///
/// @return GMM_PTE_CACHE_CONTROL_BITS: Populated PTE
/////////////////////////////////////////////////////////////////////////////////////
GMM_PTE_CACHE_CONTROL_BITS GMM_STDCALL GmmLib::GmmCachePolicyCommon::CachePolicyGetPteType(GMM_RESOURCE_USAGE_TYPE Usage)
{
__GMM_ASSERT(pGmmLibContext->GetCachePolicyElement(Usage).Initialized);
return pGmmLibContext->GetCachePolicyElement(Usage).PTE;
}

View File

@ -0,0 +1,39 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#define ISPRODUCT(X) (GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_##X)
#define FROMPRODUCT(X) (GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) >= IGFX_##X)
#define SKU(FtrXxx) (pGmmLibContext->GetSkuTable().FtrXxx != 0)
#define WA(WaXxx) (pGmmLibContext->GetWaTable().WaXxx != 0)
// Underscored to prevent name collision with the GMM_CACHE_POLICY_ELEMENT fields named L3 and LLC
#define _L3 (pGmmLibContext->GetGtSysInfo()->L3CacheSizeInKb)
#define _LLC (pGmmLibContext->GetGtSysInfo()->LLCCacheSizeInKb)
#define _ELLC (pGmmLibContext->GetGtSysInfo()->EdramSizeInKb)
#define CAM$ (SKU(FtrCameraCaptureCaching))
// Units are already in KB in the system information, so these helper macros need to account for that
#define KB(N) (N)
#define MB(N) (1024 * KB(N))

View File

@ -0,0 +1,350 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
// Generic Usages
// KMD Usages
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_BATCH_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_COMP_FRAME_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_CONTEXT_SWITCH_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_CURSOR )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_DISPLAY_STATIC_IMG_FOR_SMOOTH_ROTATION_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_DUMMY_PAGE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_GDI_SURFACE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_GENERIC_KMD_RESOURCE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_GFX_RING )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_GTT_TRANSFER_REGION )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HW_CONTEXT )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_KMD_STAGING_SURFACE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MBM_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_NNDI_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OVERLAY_MBM )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PRIMARY_SURFACE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SCREEN_PROTECTION_INTERMEDIATE_SURFACE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SHADOW_SURFACE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SM_SCRATCH_STATE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_STATE_MANAGER_KERNEL_STATE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_STATUS_PAGE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TIMER_PERF_QUEUE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_UNMAP_PAGING_RESERVED_GTT_DMA_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VSC_BATCH_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_WA_BATCH_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_KMD_OCA_BUFFER)
//
// 3D Usages
//
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_UMD_BATCH_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_BINDING_TABLE_POOL )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_CCS )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_CONSTANT_BUFFER_POOL )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_DEPTH_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_DISPLAYABLE_RENDER_TARGET )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_GEN9_UNENCRYPTED_DISPLAYABLE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_GATHER_POOL )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HEAP_SURFACE_STATE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HEAP_DYNAMIC_STATE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE_UC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT_L1_CACHED )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HEAP_INDIRECT_OBJECT )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HEAP_INSTRUCTION )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HIZ )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_INDEX_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_INDEX_BUFFER_L3_COHERENT_UC)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_INDEX_BUFFER_L3_CACHED)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MCS )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PUSH_CONSTANT_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PULL_CONSTANT_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_QUERY )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_RENDER_TARGET )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SHADER_RESOURCE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_STAGING )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_STENCIL_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_STREAM_OUTPUT_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILE_POOL )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MOCS_62 )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_L3_EVICTION )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_L3_EVICTION_SPECIAL )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_CCS_MEDIA_WRITABLE )
//TODO: To substitute with Interface to set SCF once its available for UMDs
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SHADER_RESOURCE_LLC_BYPASS )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PROCEDURAL_TEXTURE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_UNCACHED )
// Tiled Resource
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILED_CCS )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILED_DEPTH_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILED_HIZ )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILED_MCS )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILED_RENDER_TARGET )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILED_RENDER_TARGET_AND_SHADER_RESOURCE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILED_SHADER_RESOURCE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILED_UAV )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VERTEX_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VERTEX_BUFFER_L3_COHERENT_UC)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VERTEX_BUFFER_L3_CACHED)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OGL_WSTN_VERTEX_BUFFER )
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_POSH_VERTEX_BUFFER)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_UAV )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE_PARTIALENCSURFACES )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_WDDM_HISTORY_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_CONTEXT_SAVE_RESTORE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PTBR_PAGE_POOL )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PTBR_BATCH_BUFFER )
//
// CM USAGES
//
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_SurfaceState )
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_StateHeap)
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_NO_L3_SurfaceState )
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_NO_LLC_ELLC_SurfaceState )
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_NO_LLC_SurfaceState )
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_NO_ELLC_SurfaceState )
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_NO_LLC_L3_SurfaceState )
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_NO_ELLC_L3_SurfaceState )
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_NO_CACHE_SurfaceState )
DEFINE_RESOURCE_USAGE( CM_RESOURCE_USAGE_L1_Enabled_SurfaceState )
//
// MP USAGES
//
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_BEGIN )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_DEFAULT )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_DEFAULT_FF )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_DEFAULT_RCS )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_SurfaceState_FF )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_SurfaceState_RCS )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_AGE3_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_EDRAM_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_EDRAM_AGE3_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_No_L3_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_No_LLC_L3_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_No_LLC_L3_AGE_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_No_LLC_eLLC_L3_AGE_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_PartialEnc_No_LLC_L3_AGE_SurfaceState )
DEFINE_RESOURCE_USAGE( MP_RESOURCE_USAGE_END )
// MHW - SFC USAGES
DEFINE_RESOURCE_USAGE( MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface ) // SFC Output Surface
DEFINE_RESOURCE_USAGE( MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface_PartialEncSurface ) // SFC Output Surface for partial encrypted surfaces
DEFINE_RESOURCE_USAGE( MHW_RESOURCE_USAGE_Sfc_AvsLineBufferSurface ) // SFC AVS Line buffer Surface
DEFINE_RESOURCE_USAGE( MHW_RESOURCE_USAGE_Sfc_IefLineBufferSurface ) // SFC IEF Line buffer Surface
//
// CODEC USAGES
//
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_BEGIN_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC_PARTIALENCSURFACE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_POST_DEBLOCKING_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_DECODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_STREAMOUT_DATA_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_INTRA_ROWSTORE_SCRATCH_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_SCRATCH_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_REFERENCE_PICTURE_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MACROBLOCK_STATUS_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MFX_INDIRECT_MV_OBJECT_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MFD_INDIRECT_IT_COEF_OBJECT_DECODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MFC_INDIRECT_PAKBASE_OBJECT_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_BSDMPC_ROWSTORE_SCRATCH_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MPR_ROWSTORE_SCRATCH_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_BITPLANE_READ_CODEC)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_AACSBIT_VECTOR_CODEC)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_CURR_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_REF_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_FF)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_DST )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PAK_OBJECT_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_MAD_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP8_BLOCK_MODE_COST_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP8_MB_MODE_COST_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP8_MBENC_OUTPUT_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP8_HISTOGRAM_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP8_L3_LLC_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MBDISABLE_SKIPMAP_CODEC)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MFX_STANDALONE_DEBLOCKING_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_MD_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_SAO_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_MV_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_STATUS_ERROR_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_LCU_ILDB_STREAMOUT_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP9_PROBABILITY_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP9_SEGMENT_ID_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP9_HVD_ROWSTORE_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VDENC_ROW_STORE_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VDENC_STREAMIN_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_MB_QP_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MACROBLOCK_ILDB_STREAM_OUT_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SSE_SRC_PIXEL_ROW_STORE_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SLICE_STATE_STREAM_OUT_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_CABAC_SYNTAX_STREAM_OUT_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PRED_COL_STORE_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_PAK_IMAGESTATE_ENCODE)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_MBENC_BRC_ENCODE)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_MB_BRC_CONST_ENCODE)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_BRC_MB_QP_ENCODE)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_BRC_ROI_ENCODE)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_SLICE_MAP_ENCODE)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_WP_DOWNSAMPLED_ENCODE)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_VDENC_IMAGESTATE_ENCODE)
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_UNCACHED )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ELLC_ONLY )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_ONLY )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_L3 )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_SOFTWARE_SCOREBOARD_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_MV_DISTORTION_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_4XME_DISTORTION_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_INTRA_DISTORTION_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_MB_STATS_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_PAK_STATS_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_PIC_STATE_READ_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_PIC_STATE_WRITE_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_COMBINED_ENC_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_BRC_CONSTANT_DATA_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_INTERMEDIATE_CU_RECORD_SURFACE_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_SCRATCH_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_LCU_LEVEL_DATA_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ENC_HISTORY_INPUT_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ENC_HISTORY_OUTPUT_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_DEBUG_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ENC_CONSTANT_TABLE_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ENC_CU_RECORD_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ENC_MV_TEMPORAL_BUFFER_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ENC_CU_PACKET_FOR_PAK_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ENC_BCOMBINED1_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SURFACE_ENC_BCOMBINED2_ENCODE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_FRAME_STATS_STREAMOUT_DATA_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_TILE_LINE_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_TILE_COLUMN_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_MD_TILE_LINE_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_MD_TILE_COLUMN_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_SAO_TILE_LINE_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HCP_SAO_TILE_COLUMN_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_VP9_PROBABILITY_COUNTER_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_HUC_VIRTUAL_ADDR_REGION_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_SIZE_STREAMOUT_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_COMPRESSED_HEADER_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_PROBABILITY_DELTA_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILE_RECORD_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_TILE_SIZE_STAS_BUFFER_CODEC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_END_CODEC )
// OCL Usages
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_BUFFER_CONST )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_BUFFER_CSR_UC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_IMAGE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_INLINE_CONST )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_INLINE_CONST_HDC )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_SCRATCH )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_PRIVATE_MEM )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_PRINTF_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_STATE_HEAP_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER_CACHELINE_MISALIGNED )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_ISH_HEAP_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_TAG_MEMORY_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_TEXTURE_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_IMAGE_FROM_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_SELF_SNOOP_BUFFER )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_BUFFER_NO_LLC_CACHING )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_OCL_IMAGE_NO_LLC_CACHING )
// Cross Adapter
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE )
// BCS usages
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_BLT_SOURCE )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_BLT_DESTINATION )
DEFINE_RESOURCE_USAGE( GMM_RESOURCE_USAGE_CAMERA_CAPTURE )
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_MEDIA_BATCH_BUFFERS)
// DECODE
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_INPUT_BITSTREAM)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_INPUT_REFERENCE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_INTERNAL_READ)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_INTERNAL_WRITE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_INTERNAL_READ_WRITE_CACHE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_INTERNAL_READ_WRITE_NOCACHE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_OUTPUT_PICTURE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_OUTPUT_STATISTICS_WRITE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_DECODE_OUTPUT_STATISTICS_READ_WRITE)
// ENCODE
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_INPUT_RAW)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_INPUT_RECON)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_INTERNAL_READ)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_EXTERNAL_READ)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_OUTPUT_PICTURE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_OUTPUT_BITSTREAM)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_OUTPUT_STATISTICS_WRITE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_ENCODE_OUTPUT_STATISTICS_READ_WRITE)
// VP
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INPUT_PICTURE_FF)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INPUT_REFERENCE_FF)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INTERNAL_READ_FF)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INTERNAL_WRITE_FF)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_FF)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_OUTPUT_PICTURE_FF)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INPUT_PICTURE_RENDER)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INPUT_REFERENCE_RENDER)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INTERNAL_READ_RENDER)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INTERNAL_WRITE_RENDER)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_RENDER)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_VP_OUTPUT_PICTURE_RENDER)
// CP
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_CP_EXTERNAL_READ)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_CP_INTERNAL_WRITE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_GSC_KMD_RESOURCE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_KMD_NULL_CONTEXT_BB)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_COMMAND_STREAMER)
//Uncacheable copies
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_COPY_SOURCE)
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_COPY_DEST)
// Shader resource uncachable, needed for WA_18013889147
DEFINE_RESOURCE_USAGE(GMM_RESOURCE_USAGE_SHADER_RESOURCE_L1_NOT_CACHED)

View File

@ -0,0 +1,30 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#undef PRODUCT
#undef SKU
#undef WA
#undef _L3
#undef _LLC
#undef _ELLC
#undef KB
#undef MB

View File

@ -0,0 +1,466 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmCachePolicy.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen10.h"
//=============================================================================
//
// Function: __GmmGen10InitCachePolicy
//
// Desc: This function initializes the cache policy
//
// Parameters: pCachePolicy -> Ptr to array to be populated with the
// mapping of usages -> cache settings.
//
// Return: GMM_STATUS
//
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::GmmGen10CachePolicy::InitCachePolicy()
{
__GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
#define DEFINE_CACHE_ELEMENT(usage, llc, ellc, l3, wt, age, lecc_scc, l3_scc, sso, cos, hdcl1) DEFINE_CP_ELEMENT(usage, llc, ellc, l3, wt, age, 0, lecc_scc, l3_scc, 0, sso, cos, hdcl1, 0, 0, 0, 0, 0)
#include "GmmGen10CachePolicy.h"
#define TC_LLC (1)
#define TC_ELLC (0) //Is this supported anymore in TargetCache?
#define TC_LLC_ELLC (2)
#define LeCC_UNCACHEABLE (0x1)
#define LeCC_WT_CACHEABLE (0x2) //Only used as MemPushWRite disqualifier if set along with eLLC-only
#define LeCC_WB_CACHEABLE (0x3)
#define L3_UNCACHEABLE (0x1)
#define L3_WB_CACHEABLE (0x3)
#define DISABLE_SKIP_CACHING_CONTROL (0x0)
#define ENABLE_SKIP_CACHING_CONTROL (0x1)
#define DISABLE_SELF_SNOOP_OVERRIDE (0x0)
#define ENABLE_SELF_SNOOP_OVERRIDE (0x1)
#define ENABLE_SELF_SNOOP_ALWAYS (0x3)
#define CLASS_SERVICE_ZERO 0
{
// Define index of cache element
uint32_t Usage = 0;
uint32_t CurrentMaxIndex = 0;
uint32_t CurrentMaxHDCL1Index = GMM_GEN10_HDCL1_MOCS_INDEX_START - 1; // define constant
GMM_CACHE_POLICY_TBL_ELEMENT *pCachePolicyTlbElement = pGmmLibContext->GetCachePolicyTlbElement();
// index 0 is uncached.
{
GMM_CACHE_POLICY_TBL_ELEMENT *Entry0 = &(pCachePolicyTlbElement[0]);
Entry0->LeCC.Cacheability = LeCC_UNCACHEABLE;
Entry0->LeCC.TargetCache = TC_LLC_ELLC;
Entry0->LeCC.LRUM = 0;
Entry0->LeCC.ESC = DISABLE_SKIP_CACHING_CONTROL;
Entry0->LeCC.SCC = 0;
Entry0->LeCC.CoS = CLASS_SERVICE_ZERO;
Entry0->LeCC.SelfSnoop = DISABLE_SELF_SNOOP_OVERRIDE;
Entry0->L3.Cacheability = L3_UNCACHEABLE;
Entry0->L3.ESC = DISABLE_SKIP_CACHING_CONTROL;
Entry0->L3.SCC = 0;
Entry0->HDCL1 = 0;
}
// Process the cache policy and fill in the look up table
for(; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
bool CachePolicyError = false;
int32_t CPTblIdx = -1;
uint32_t j = 0;
uint64_t PTEValue = 0;
GMM_CACHE_POLICY_TBL_ELEMENT UsageEle = {0};
UsageEle.LeCC.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned LeCC.DwordValue.
UsageEle.LeCC.SelfSnoop = DISABLE_SELF_SNOOP_OVERRIDE;
UsageEle.LeCC.CoS = CLASS_SERVICE_ZERO;
UsageEle.LeCC.SCC = 0;
UsageEle.LeCC.ESC = 0;
if(pCachePolicy[Usage].SSO & ENABLE_SELF_SNOOP_OVERRIDE)
{
UsageEle.LeCC.SelfSnoop = pCachePolicy[Usage].SSO & ENABLE_SELF_SNOOP_ALWAYS;
}
if(pCachePolicy[Usage].CoS)
{
UsageEle.LeCC.CoS = pCachePolicy[Usage].CoS;
}
if(pCachePolicy[Usage].HDCL1)
{
UsageEle.HDCL1 = 1;
}
if(pCachePolicy[Usage].LeCC_SCC)
{
UsageEle.LeCC.SCC = pCachePolicy[Usage].LeCC_SCC;
UsageEle.LeCC.ESC = ENABLE_SKIP_CACHING_CONTROL;
}
UsageEle.LeCC.LRUM = pCachePolicy[Usage].AGE;
// default to LLC/ELLC target cache.
UsageEle.LeCC.TargetCache = TC_LLC_ELLC;
UsageEle.LeCC.Cacheability = LeCC_WB_CACHEABLE;
if(pCachePolicy[Usage].LLC && pCachePolicy[Usage].ELLC)
{
UsageEle.LeCC.TargetCache = TC_LLC_ELLC;
}
else if(pCachePolicy[Usage].LLC)
{
UsageEle.LeCC.TargetCache = TC_LLC;
}
else if(pCachePolicy[Usage].ELLC)
{
UsageEle.LeCC.TargetCache = TC_ELLC;
if(pCachePolicy[Usage].WT)
{
UsageEle.LeCC.Cacheability = LeCC_WT_CACHEABLE;
}
}
else
{
UsageEle.LeCC.Cacheability = LeCC_UNCACHEABLE;
}
UsageEle.L3.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned L3.UshortValue.
UsageEle.L3.ESC = DISABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = 0;
UsageEle.L3.Cacheability = pCachePolicy[Usage].L3 ? L3_WB_CACHEABLE : L3_UNCACHEABLE;
if(pCachePolicy[Usage].L3_SCC)
{
UsageEle.L3.ESC = ENABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = (uint16_t)pCachePolicy[Usage].L3_SCC;
}
//For HDC L1 caching, MOCS Table index 48-61 should be used
if(UsageEle.HDCL1)
{
for(j = GMM_GEN10_HDCL1_MOCS_INDEX_START; j <= CurrentMaxHDCL1Index; j++)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pCachePolicyTlbElement[j];
if(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
TblEle->L3.UshortValue == UsageEle.L3.UshortValue &&
TblEle->HDCL1 == UsageEle.HDCL1)
{
CPTblIdx = j;
break;
}
}
}
else
{
for(j = 0; j <= CurrentMaxIndex; j++)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pCachePolicyTlbElement[j];
if(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
TblEle->L3.UshortValue == UsageEle.L3.UshortValue &&
TblEle->HDCL1 == UsageEle.HDCL1)
{
CPTblIdx = j;
break;
}
}
}
// Didn't find the caching settings in one of the already programmed lookup table entries.
// Need to add a new lookup table entry.
if(CPTblIdx == -1)
{
if(UsageEle.HDCL1 && CurrentMaxHDCL1Index < GMM_GEN9_MAX_NUMBER_MOCS_INDEXES - 1)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &(pCachePolicyTlbElement[++CurrentMaxHDCL1Index]);
CPTblIdx = CurrentMaxHDCL1Index;
TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
TblEle->L3.UshortValue = UsageEle.L3.UshortValue;
TblEle->HDCL1 = UsageEle.HDCL1;
}
else if(CurrentMaxIndex < GMM_GEN10_HDCL1_MOCS_INDEX_START)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &(pCachePolicyTlbElement[++CurrentMaxIndex]);
CPTblIdx = CurrentMaxIndex;
TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
TblEle->L3.UshortValue = UsageEle.L3.UshortValue;
TblEle->HDCL1 = UsageEle.HDCL1;
}
else
{
// Too many unique caching combinations to program the
// MOCS lookup table.
CachePolicyError = true;
GMM_ASSERTDPF(
"Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
"(we only support GMM_GEN_MAX_NUMBER_MOCS_INDEXES = %d)",
GMM_GEN9_MAX_NUMBER_MOCS_INDEXES - 1);
// Set cache policy index to uncached.
CPTblIdx = 0;
}
}
// PTE entries do not control caching on SKL+ (for legacy context)
if(!GetUsagePTEValue(pCachePolicy[Usage], Usage, &PTEValue))
{
CachePolicyError = true;
}
pCachePolicy[Usage].PTE.DwordValue = PTEValue & 0xFFFFFFFF;
pCachePolicy[Usage].PTE.HighDwordValue = 0;
pCachePolicy[Usage].MemoryObjectOverride.Gen10.Index = CPTblIdx;
pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
if(CachePolicyError)
{
GMM_ASSERTDPF("Cache Policy Init Error: Invalid Cache Programming - Element %d", Usage);
}
}
CurrentMaxMocsIndex = CurrentMaxIndex;
CurrentMaxL1HdcMocsIndex = CurrentMaxHDCL1Index;
}
return GMM_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Initializes WA's needed for setting up the Private PATs
/// WaNoMocsEllcOnly, WaGttPat0, WaGttPat0GttWbOverOsIommuEllcOnly, WaGttPat0WB
///
/// @return GMM_STATUS
///
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmGen10CachePolicy::SetPATInitWA()
{
GMM_STATUS Status = GMM_SUCCESS;
#if(defined(__GMM_KMD__))
if(pGmmLibContext->GetGtSysInfoPtr()->EdramSizeInKb)
{
const_cast<WA_TABLE &>(pGmmLibContext->GetWaTable()).WaNoMocsEllcOnly = 1;
}
#else
Status = GMM_ERROR;
#endif
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the PAT idx that best matches the cache policy for this usage.
///
/// @param: CachePolicy: cache policy for a usage
///
/// @return PAT Idx to use in the PTE
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmGen10CachePolicy::BestMatchingPATIdx(GMM_CACHE_POLICY_ELEMENT CachePolicy)
{
uint32_t i;
uint32_t PATIdx = 0;
GMM_GFX_MEMORY_TYPE WantedMemoryType = GMM_GFX_UC_WITH_FENCE, MemoryType;
GMM_GFX_TARGET_CACHE WantedTC = GMM_GFX_TC_ELLC_LLC;
WantedMemoryType = GetWantedMemoryType(CachePolicy);
if(CachePolicy.LLC && CachePolicy.ELLC)
{
WantedTC = GMM_GFX_TC_ELLC_LLC;
}
else if(CachePolicy.LLC)
{
WantedTC = GMM_GFX_TC_LLC_ONLY;
}
else if(CachePolicy.ELLC)
{
WantedTC = GMM_GFX_TC_ELLC_ONLY; // Note: this overrides the MOCS target cache selection.
}
for(i = 1; i < GMM_NUM_PAT_ENTRIES; i++)
{
GMM_PRIVATE_PAT PAT1 = GetPrivatePATEntry(PATIdx);
GMM_PRIVATE_PAT PAT2 = GetPrivatePATEntry(i);
if(SelectNewPATIdx(WantedMemoryType, WantedTC,
(GMM_GFX_MEMORY_TYPE)PAT1.Gen10.MemoryType, (GMM_GFX_TARGET_CACHE)PAT1.Gen10.TargetCache,
(GMM_GFX_MEMORY_TYPE)PAT2.Gen10.MemoryType, (GMM_GFX_TARGET_CACHE)PAT2.Gen10.TargetCache))
{
PATIdx = i;
}
}
MemoryType = (GMM_GFX_MEMORY_TYPE)GetPrivatePATEntry(PATIdx).Gen10.MemoryType;
if(MemoryType != WantedMemoryType)
{
// Failed to find a matching PAT entry
return GMM_PAT_ERROR;
}
return PATIdx;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Initializes the Gfx PAT tables for AdvCtx and Gfx MMIO/Private PAT
/// PAT0 = WB_COHERENT or UC depending on WaGttPat0WB
/// PAT1 = UC or WB_COHERENT depending on WaGttPat0WB
/// PAT2 = WB_MOCSLESS, with TC = eLLC+LLC
/// PAT3 = WB
/// PAT4 = WT
/// PAT5 = WC
/// PAT6 = WC
/// PAT7 = WC
/// HLD says to set to PAT0/1 to WC, but since we don't have a WC in GPU,
/// WC option is same as UC. Hence setting PAT0 or PAT1 to UC.
/// Unused PAT's (5,6,7) are set to WC.
///
/// @return GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmGen10CachePolicy::SetupPAT()
{
GMM_STATUS Status = GMM_SUCCESS;
#if(defined(__GMM_KMD__))
uint32_t i = 0;
GMM_GFX_MEMORY_TYPE GfxMemType = GMM_GFX_UC_WITH_FENCE;
// No optional selection on Age or Target Cache because for an SVM-OS Age and
// Target Cache would not work [for an SVM-OS the Page Table is shared with IA
// and we don't have control of the PAT Idx]. If there is a strong ask from D3D
// or the performance analysis team, Age could be added.
// Add Class of Service when required.
GMM_GFX_TARGET_CACHE GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
uint8_t Age = 1;
uint8_t ServiceClass = 0;
int32_t * pPrivatePATTableMemoryType = NULL;
pPrivatePATTableMemoryType = pGmmLibContext->GetPrivatePATTableMemoryType();
__GMM_ASSERT(pGmmLibContext->GetSkuTable().FtrIA32eGfxPTEs);
for(i = 0; i < GMM_NUM_GFX_PAT_TYPES; i++)
{
pPrivatePATTableMemoryType[i] = -1;
}
// Set values for GmmGlobalInfo PrivatePATTable
for(i = 0; i < GMM_NUM_PAT_ENTRIES; i++)
{
GMM_PRIVATE_PAT PAT = {0};
if(pGmmLibContext->GetWaTable().WaNoMocsEllcOnly)
{
GfxTargetCache = GMM_GFX_TC_ELLC_ONLY;
}
else
{
GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
}
switch(i)
{
case PAT0:
if(pGmmLibContext->GetWaTable().WaGttPat0)
{
if(pGmmLibContext->GetWaTable().WaGttPat0WB)
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
}
else
{
GfxMemType = GMM_GFX_UC_WITH_FENCE;
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT0;
}
}
else // if GTT is not tied to PAT0 then WaGttPat0WB is NA
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
}
break;
case PAT1:
if(pGmmLibContext->GetWaTable().WaGttPat0 && !pGmmLibContext->GetWaTable().WaGttPat0WB)
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT1;
}
else
{
GfxMemType = GMM_GFX_UC_WITH_FENCE;
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT1;
}
break;
case PAT2:
// This PAT idx shall be used for MOCS'Less resources like Page Tables
// Page Tables have TC hardcoded to eLLC+LLC in Adv Ctxt. Hence making this to have same in Leg Ctxt.
// For BDW-H, due to Perf issue, TC has to be eLLC only for Page Tables when eDRAM is present.
GfxMemType = GMM_GFX_WB;
GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_MOCSLESS] = PAT2;
break;
case PAT3:
GfxMemType = GMM_GFX_WB;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB] = PAT3;
break;
case PAT4:
GfxMemType = GMM_GFX_WT;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WT] = PAT4;
break;
case PAT5:
case PAT6:
case PAT7:
GfxMemType = GMM_GFX_WC;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WC] = PAT5;
break;
default:
__GMM_ASSERT(0);
Status = GMM_ERROR;
}
PAT.Gen10.MemoryType = GfxMemType;
PAT.Gen10.TargetCache = GfxTargetCache;
PAT.Gen10.Age = Age;
PAT.Gen10.CoS = ServiceClass;
SetPrivatePATEntry(i, PAT);
}
#else
Status = GMM_ERROR;
#endif
return Status;
}

View File

@ -0,0 +1,242 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmCachePolicyConditionals.h"
#define EDRAM (SKU(FtrEDram))
#define FBLLC (SKU(FtrFrameBufferLLC))
//eDRAM-Only caching, for a usage that might be encrypted, must use ENCRYPTED_PARTIALS_EDRAM
#define ENCRYPTED_PARTIALS_EDRAM (EDRAM && !(pGmmLibContext->GetWaTable().WaEncryptedEdramOnlyPartials))
// Cache Policy Definition
// AOM = Do not allocate on miss (0 = allocate on miss [normal cache behavior], 1 = don't allocate on miss)
// LeCC_SCC = LLC/eLLC skip caching control (disabled if LeCC_SCC = 0)
// L3_SCC = L3 skip caching control (disabled if L3_SCC = 0)
// SSO = Override MIDI self snoop settings (1 = never send to uncore, 3 = always send to uncore, 0 = [default] No override )
// CoS = Class of Service ( allowed values 1, 2, 3 for class IDs 1, 2, 3 respectively, default class 1 => driver overrides 0->1)
// HDCL1 = HDC L1 cache control (1 = cached in HDC L1, 0 = not cached in HDC L1)
// Faster PushWrite(Gen10+) used iff !WT, eLLC-only cacheable - Globally visible surface (eg display surface) should be marked WT
//***************************************************************************************************************/
// USAGE TYPE , LLC , ELLC , L3 , WT , AGE , LeCC_SCC , L3_SCC, SSO, CoS, HDCL1 )
/****************************************************************************************************************/
// KMD Usages
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMP_FRAME_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SWITCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CURSOR , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAY_STATIC_IMG_FOR_SMOOTH_ROTATION_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DUMMY_PAGE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GDI_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GENERIC_KMD_RESOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
// GMM_RESOURCE_USAGE_GFX_RING is only used if WaEnableRingHostMapping is enabled.
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GFX_RING , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GTT_TRANSFER_REGION , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HW_CONTEXT , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATE_MANAGER_KERNEL_STATE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_STAGING_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBM_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_NNDI_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OVERLAY_MBM , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRIMARY_SURFACE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SCREEN_PROTECTION_INTERMEDIATE_SURFACE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADOW_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SM_SCRATCH_STATE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATUS_PAGE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TIMER_PERF_QUEUE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNKNOWN , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNMAP_PAGING_RESERVED_GTT_DMA_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VSC_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WA_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_OCA_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
//
// 3D Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UMD_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BINDING_TABLE_POOL , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CCS , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONSTANT_BUFFER_POOL , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEPTH_BUFFER , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAYABLE_RENDER_TARGET , FBLLC, ENCRYPTED_PARTIALS_EDRAM, FBLLC, !FBLLC && ENCRYPTED_PARTIALS_EDRAM, 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GATHER_POOL , 0 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_SURFACE_STATE , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_DYNAMIC_STATE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE_UC , 0 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INDIRECT_OBJECT , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INSTRUCTION , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HIZ , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MCS , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PUSH_CONSTANT_BUFFER , 0 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PULL_CONSTANT_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_QUERY , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STAGING , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STENCIL_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAM_OUTPUT_BUFFER , 0 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROCEDURAL_TEXTURE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
// Tiled Resource
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_DEPTH_BUFFER , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_HIZ , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_MCS , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_CCS , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_SHADER_RESOURCE , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_UAV , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UAV , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OGL_WSTN_VERTEX_BUFFER , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WDDM_HISTORY_BUFFER , 0 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SAVE_RESTORE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
//
// CM USAGES
//
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_SurfaceState, 1 , 1 , 1 , 0 ,3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_L3_SurfaceState, 1 , 1 , 0 , 0 ,3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_ELLC_SurfaceState, 0 , 0 , 1 , 0 ,3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_SurfaceState, 0 , 1 , 1 , 0 ,3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_ELLC_SurfaceState, 1 , 0 , 1 , 0 ,3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_L3_SurfaceState, 0 , 1 , 0 , 0 ,3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_ELLC_L3_SurfaceState, 1 , 0 , 0 , 0 ,3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_CACHE_SurfaceState, 0 , 0 , 0 , 0 ,3, 0, 0, 0, 0, 0);
//
// MP USAGES
//
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_BEGIN, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_DEFAULT, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_SurfaceState, 1 , EDRAM, 1 , 0 , 1, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_AGE3_SurfaceState, 1 , EDRAM, 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_END, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
// MHW - SFC
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_AvsLineBufferSurface, 1 , EDRAM, 1 , 0 , 1, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_IefLineBufferSurface, 1 , EDRAM, 1 , 0 , 1, 0, 0, 0, 0, 0);
//Media GMM Resource USAGES
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POST_DEBLOCKING_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_ENCODE , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_DECODE , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAMOUT_DATA_CODEC , 0 , 0 , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INTRA_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_REFERENCE_PICTURE_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_STATUS_BUFFER_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_MV_OBJECT_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFD_INDIRECT_IT_COEF_OBJECT_DECODE , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFC_INDIRECT_PAKBASE_OBJECT_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BSDMPC_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MPR_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BITPLANE_READ_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_AACSBIT_VECTOR_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_CURR_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_REF_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_DST , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PAK_OBJECT_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_ROW_STORE_BUFFER_CODEC , 1 , 0 , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_STREAMIN_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MB_QP_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_COUNTER_BUFFER_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HUC_VIRTUAL_ADDR_REGION_BUFFER_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SIZE_STREAMOUT_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMPRESSED_HEADER_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROBABILITY_DELTA_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MV_CODEC , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_STATUS_ERROR_CODEC , 0 , 0 , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_LCU_ILDB_STREAMOUT_CODEC , 0 , 0 , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_SEGMENT_ID_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_HVD_ROWSTORE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_ILDB_STREAM_OUT_BUFFER_CODEC , 0 , 0 , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SSE_SRC_PIXEL_ROW_STORE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_UNCACHED , 0 , 0 , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_ONLY , 0 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_ONLY , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_L3 , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0);
/**********************************************************************************/
//
// OCL Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CONST , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CSR_UC , 0 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_IMAGE , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST_HDC , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SCRATCH , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRIVATE_MEM , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRINTF_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_STATE_HEAP_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER_CACHELINE_MISALIGNED , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_ISH_HEAP_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TAG_MEMORY_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TEXTURE_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_IMAGE_FROM_BUFFER , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SELF_SNOOP_BUFFER , 1 , 0 , 1 , 0 , 3 , 0, 0, 3, 0, 0);
/**********************************************************************************/
// Cross Adapter
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
/**********************************************************************************/
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CAMERA_CAPTURE , CAM$, 0 , 0 , 0 , CAM$ , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMMAND_STREAMER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
// Uncacheable copies
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_SOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_DEST , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0);
#include "GmmCachePolicyUndefineConditionals.h"

View File

@ -0,0 +1,361 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmCachePolicy.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen10.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen11.h"
//=============================================================================
//
// Function: IsSpecialMOCSUsage
//
// Desc: This function returns special(hw-reserved) MocsIdx based on usage
//
// Parameters: usage -> Resource usage type
// UpdateMOCS -> True if MOCS Table must be updated, ow false
//
// Return: int32_t
//
//-----------------------------------------------------------------------------
int32_t GmmLib::GmmGen11CachePolicy::IsSpecialMOCSUsage(GMM_RESOURCE_USAGE_TYPE Usage, bool &UpdateMOCS)
{
int32_t MocsIdx = -1;
UpdateMOCS = true;
switch(Usage)
{
case GMM_RESOURCE_USAGE_MOCS_62:
__GMM_ASSERT(pCachePolicy[Usage].L3 == 0); //Architecturally, TR/Aux-TT node isn't L3-cacheable.
pCachePolicy[Usage].L3 = 0;
MocsIdx = 62;
break;
case GMM_RESOURCE_USAGE_L3_EVICTION:
pCachePolicy[Usage].L3 = 0;
MocsIdx = 63;
break;
default:
UpdateMOCS = false;
break;
}
return MocsIdx;
}
//=============================================================================
//
// Function: __GmmGen11InitCachePolicy
//
// Desc: This function initializes the cache policy
//
// Parameters: pCachePolicy -> Ptr to array to be populated with the
// mapping of usages -> cache settings.
//
// Return: GMM_STATUS
//
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::GmmGen11CachePolicy::InitCachePolicy()
{
__GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
#define DEFINE_CACHE_ELEMENT(usage, llc, ellc, l3, wt, age, aom, lecc_scc, l3_scc, scf, sso, cos) DEFINE_CP_ELEMENT(usage, llc, ellc, l3, wt, age, aom, lecc_scc, l3_scc, scf, sso, cos, 0, 0, 0, 0, 0, 0)
#include "GmmGen11CachePolicy.h"
#define TC_LLC (1)
#define TC_ELLC (0) //Is this supported anymore in TargetCache?
#define TC_LLC_ELLC (2)
#define LeCC_UNCACHEABLE (0x1)
#define LeCC_WT_CACHEABLE (0x2) //Only used as MemPushWRite disqualifier if set along with eLLC-only
#define LeCC_WB_CACHEABLE (0x3)
#define L3_UNCACHEABLE (0x1)
#define L3_WB_CACHEABLE (0x3)
#define DISABLE_SKIP_CACHING_CONTROL (0x0)
#define ENABLE_SKIP_CACHING_CONTROL (0x1)
#define DISABLE_SELF_SNOOP_OVERRIDE (0x0)
#define ENABLE_SELF_SNOOP_OVERRIDE (0x1)
#define ENABLE_SELF_SNOOP_ALWAYS (0x3)
#define CLASS_SERVICE_ZERO (0x0)
// Setup Static MOCS Table
{
this->SetUpMOCSTable();
}
{
// Define index of cache element
uint32_t Usage = 0;
uint32_t CurrentMaxSpecialIndex = GMM_GEN9_MAX_NUMBER_MOCS_INDEXES - 1;
#if(_WIN32 && (_DEBUG || _RELEASE_INTERNAL))
OverrideCachePolicy();
#endif
// Process the cache policy and fill in the look up table
for(; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
bool CachePolicyError = false;
bool SpecialMOCS = false;
int32_t CPTblIdx = -1;
uint32_t j = 0;
uint64_t PTEValue = 0;
GMM_CACHE_POLICY_TBL_ELEMENT UsageEle = {0};
CPTblIdx = IsSpecialMOCSUsage((GMM_RESOURCE_USAGE_TYPE)Usage, SpecialMOCS);
UsageEle.LeCC.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned LeCC.DwordValue.
UsageEle.LeCC.SelfSnoop = DISABLE_SELF_SNOOP_OVERRIDE;
UsageEle.LeCC.CoS = CLASS_SERVICE_ZERO;
UsageEle.LeCC.SCC = 0;
UsageEle.LeCC.ESC = 0;
if(pCachePolicy[Usage].SCF && pGmmLibContext->GetSkuTable().FtrLLCBypass)
{
UsageEle.LeCC.SCF = pCachePolicy[Usage].SCF;
}
if(pCachePolicy[Usage].SSO & ENABLE_SELF_SNOOP_OVERRIDE)
{
UsageEle.LeCC.SelfSnoop = pCachePolicy[Usage].SSO & ENABLE_SELF_SNOOP_ALWAYS;
}
if(pCachePolicy[Usage].CoS)
{
UsageEle.LeCC.CoS = pCachePolicy[Usage].CoS;
}
if(pCachePolicy[Usage].LeCC_SCC)
{
UsageEle.LeCC.SCC = pCachePolicy[Usage].LeCC_SCC;
UsageEle.LeCC.ESC = ENABLE_SKIP_CACHING_CONTROL;
}
UsageEle.LeCC.LRUM = pCachePolicy[Usage].AGE;
// default to LLC target cache.
UsageEle.LeCC.TargetCache = TC_LLC;
UsageEle.LeCC.Cacheability = LeCC_WB_CACHEABLE;
if(pCachePolicy[Usage].LLC)
{
UsageEle.LeCC.TargetCache = TC_LLC;
}
else
{
UsageEle.LeCC.Cacheability = LeCC_UNCACHEABLE;
}
UsageEle.L3.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned L3.UshortValue.
UsageEle.L3.ESC = DISABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = 0;
UsageEle.L3.Cacheability = pCachePolicy[Usage].L3 ? L3_WB_CACHEABLE : L3_UNCACHEABLE;
if(pCachePolicy[Usage].L3_SCC)
{
UsageEle.L3.ESC = ENABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = (uint16_t)pCachePolicy[Usage].L3_SCC;
}
if(CPTblIdx >= GMM_GEN9_MAX_NUMBER_MOCS_INDEXES)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[CPTblIdx];
CurrentMaxSpecialIndex = ((uint32_t)CPTblIdx > CurrentMaxSpecialIndex) ? (uint32_t)CPTblIdx : CurrentMaxSpecialIndex;
if(SpecialMOCS && //Update if one of special MOCS enums
!(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
TblEle->L3.UshortValue == UsageEle.L3.UshortValue))
{
//Assert if being overwritten!
__GMM_ASSERT(TblEle->LeCC.DwordValue == 0 &&
TblEle->L3.UshortValue == 0);
}
}
else
{
for(j = 1; j <= CurrentMaxMocsIndex; j++)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[j];
if(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
TblEle->L3.UshortValue == UsageEle.L3.UshortValue)
{
CPTblIdx = j;
break;
}
}
}
// Didn't find the caching settings in one of the already programmed Explicit Mocs lookup table entries
// Need to add a new explicit mocs lookup table entry.
if(CPTblIdx == -1)
{
#if(_WIN32 && (_DEBUG || _RELEASE_INTERNAL))
// If the Cache Policy setting is overriden through regkey,
// don't raise an assert/log error. Raising an assert for debug/perf testing isn't really helpful
if(pCachePolicy[Usage].IsOverridenByRegkey)
{
if(CurrentMaxMocsIndex < GMM_GEN9_MAX_NUMBER_MOCS_INDEXES - 1)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &(pGmmLibContext->GetCachePolicyTlbElement()[++CurrentMaxMocsIndex]);
CPTblIdx = CurrentMaxMocsIndex;
TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
TblEle->L3.UshortValue = UsageEle.L3.UshortValue;
}
else
{
// Too many unique caching combinations to program the
// MOCS lookup table.
CachePolicyError = true;
GMM_ASSERTDPF(
"Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
"(we only support GMM_GEN_MAX_NUMBER_MOCS_INDEXES = %d)",
GMM_GEN9_MAX_NUMBER_MOCS_INDEXES - 1);
// Set cache policy index to uncached.
CPTblIdx = 0;
}
}
else
#endif
{
GMM_ASSERTDPF(false, "CRITICAL ERROR: Cache Policy Usage value specified by Client in not defined in Fixed MOCS Table!");
// Log Error using regkey to indicate the above error
#if(_WIN32 && (_DEBUG || _RELEASE_INTERNAL) && __GMM_KMD__)
REGISTRY_OVERRIDE_WRITE(Usage, NewMOCSEntryLeCCValue, UsageEle.LeCC.DwordValue);
REGISTRY_OVERRIDE_WRITE(Usage, NewMOCSEntryL3Value, UsageEle.L3.UshortValue);
#endif
CachePolicyError = true;
GMM_ASSERTDPF(
"Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
"(we only support GMM_GEN_MAX_NUMBER_MOCS_INDEXES = %d)",
CurrentMaxMocsIndex);
// Set cache policy index to uncached.
CPTblIdx = 0;
}
}
// PTE entries do not control caching on SKL+ (for legacy context)
if(!GetUsagePTEValue(pCachePolicy[Usage], Usage, &PTEValue))
{
CachePolicyError = true;
}
pCachePolicy[Usage].PTE.DwordValue = PTEValue & 0xFFFFFFFF;
pCachePolicy[Usage].PTE.HighDwordValue = 0;
pCachePolicy[Usage].MemoryObjectOverride.Gen11.Index = CPTblIdx;
pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
if(CachePolicyError)
{
GMM_ASSERTDPF("Cache Policy Init Error: Invalid Cache Programming - Element %d", Usage);
}
}
CurrentMaxSpecialMocsIndex = CurrentMaxSpecialIndex;
}
return GMM_SUCCESS;
}
//=============================================================================
//
// Function: SetUpMOCSTable
//
// Desc:
//
// Parameters:
//
// Return: GMM_STATUS
//
//-----------------------------------------------------------------------------
void GmmLib::GmmGen11CachePolicy::SetUpMOCSTable()
{
GMM_CACHE_POLICY_TBL_ELEMENT *pCachePolicyTlbElement = &(pGmmLibContext->GetCachePolicyTlbElement()[0]);
#define GMM_DEFINE_MOCS(Index, L3_ESC, L3_SCC, L3_CC, LeCC_CC, LeCC_TC, LeCC_LRUM, LeCC_AOM, LeCC_ESC, LeCC_SCC, LeCC_PFM, LeCC_SCF, LeCC_CoS, LeCC_SelfSnoop) \
{ \
pCachePolicyTlbElement[Index].L3.ESC = L3_ESC; \
pCachePolicyTlbElement[Index].L3.SCC = L3_SCC; \
pCachePolicyTlbElement[Index].L3.Cacheability = L3_CC; \
pCachePolicyTlbElement[Index].LeCC.Cacheability = LeCC_CC; \
pCachePolicyTlbElement[Index].LeCC.TargetCache = LeCC_TC; \
pCachePolicyTlbElement[Index].LeCC.LRUM = LeCC_LRUM; \
pCachePolicyTlbElement[Index].LeCC.AOM = LeCC_AOM; \
pCachePolicyTlbElement[Index].LeCC.ESC = LeCC_ESC; \
pCachePolicyTlbElement[Index].LeCC.SCC = LeCC_SCC; \
pCachePolicyTlbElement[Index].LeCC.PFM = LeCC_PFM; \
pCachePolicyTlbElement[Index].LeCC.SCF = LeCC_SCF; \
pCachePolicyTlbElement[Index].LeCC.CoS = LeCC_CoS; \
pCachePolicyTlbElement[Index].LeCC.SelfSnoop = LeCC_SelfSnoop; \
}
// clang-format off
//Default MOCS Table
for(int index = 0; index < GMM_MAX_NUMBER_MOCS_INDEXES; index++)
{ // Index ESC SCC L3CC LeCC TC LRUM DAoM ERSC SCC PFM SCF CoS SSE
GMM_DEFINE_MOCS(index , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
}
// Explicit MOCS Table
// Index ESC SCC L3CC LeCC TC LRUM DAoM ERSC SCC PFM SCF CoS SSE
GMM_DEFINE_MOCS( 1 , 0 , 0 , 3 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 2 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 3 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 4 , 0 , 0 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 5 , 0 , 0 , 1 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 6 , 0 , 0 , 1 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 7 , 0 , 0 , 3 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 8 , 0 , 0 , 1 , 3 , 1 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 9 , 0 , 0 , 3 , 3 , 1 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 10 , 0 , 0 , 1 , 3 , 1 , 3 , 1 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 11 , 0 , 0 , 3 , 3 , 1 , 3 , 1 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 12 , 0 , 0 , 1 , 3 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 13 , 0 , 0 , 3 , 3 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 14 , 0 , 0 , 1 , 3 , 1 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 15 , 0 , 0 , 3 , 3 , 1 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 16 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 17 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 18 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 3 )
GMM_DEFINE_MOCS( 19 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 7 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 20 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 3 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 21 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 1 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 22 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 1 , 3 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 23 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 1 , 7 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 62 , 0 , 0 , 1 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 63 , 0 , 0 , 1 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
if(pGmmLibContext->GetSkuTable().FtrLLCBypass)
{
GMM_DEFINE_MOCS( 16 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 )
GMM_DEFINE_MOCS( 17 , 0 , 0 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 )
}
CurrentMaxMocsIndex = 23;
// clang-format on
#undef GMM_DEFINE_MOCS
}

View File

@ -0,0 +1,292 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmCachePolicyConditionals.h"
#define EDRAM (SKU(FtrEDram))
#define FBLLC (SKU(FtrFrameBufferLLC))
#define NS (SKU(FtrLLCBypass))
// Cache Policy Definition
// AOM = Do not allocate on miss (0 = allocate on miss [normal cache behavior], 1 = don't allocate on miss)
// LeCC_SCC = LLC/eLLC skip caching control (disabled if LeCC_SCC = 0)
// L3_SCC = L3 skip caching control (disabled if L3_SCC = 0)
// SCF = Snoop Control Field (SCF)- Only for SKL/BXT(as coherent/non-coherent)
// SSO = Override MIDI self snoop settings (1 = never send to uncore, 3 = always send to uncore, 0 = [default] No override )
// CoS = Class of Service ( allowed values 1, 2, 3 for class IDs 1, 2, 3 respectively, default class 1 => driver overrides 0->1)
// Faster PushWrite(Gen10+) used iff !WT, eLLC-only cacheable - Globally visible surface (eg display surface) should be marked WT
//***************************************************************************************************************/
// USAGE TYPE , LLC , ELLC , L3 , WT , AGE , AOM , LeCC_SCC , L3_SCC, SCF, SSO, CoS)
/****************************************************************************************************************/
// KMD Usages
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMP_FRAME_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SWITCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CURSOR , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAY_STATIC_IMG_FOR_SMOOTH_ROTATION_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DUMMY_PAGE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GDI_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GENERIC_KMD_RESOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
// GMM_RESOURCE_USAGE_GFX_RING is only used if WaEnableRingHostMapping is enabled.
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GFX_RING , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GTT_TRANSFER_REGION , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HW_CONTEXT , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATE_MANAGER_KERNEL_STATE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_STAGING_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBM_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_NNDI_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OVERLAY_MBM , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRIMARY_SURFACE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, NS, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SCREEN_PROTECTION_INTERMEDIATE_SURFACE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADOW_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SM_SCRATCH_STATE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATUS_PAGE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TIMER_PERF_QUEUE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNKNOWN , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNMAP_PAGING_RESERVED_GTT_DMA_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VSC_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WA_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_OCA_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
//
// 3D Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UMD_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BINDING_TABLE_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CCS , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONSTANT_BUFFER_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEPTH_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAYABLE_RENDER_TARGET , 0 , EDRAM, 0 , EDRAM , 0 , 0, 0, 0, NS, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GATHER_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_SURFACE_STATE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_DYNAMIC_STATE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE_UC , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT_L1_CACHED , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INDIRECT_OBJECT , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INSTRUCTION , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HIZ , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER_L3_COHERENT_UC , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER_L3_CACHED , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MCS , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PUSH_CONSTANT_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PULL_CONSTANT_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_QUERY , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE , 0 , 1 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STAGING , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STENCIL_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAM_OUTPUT_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE_LLC_BYPASS , 0 , 1 , 1 , 0 , 0 , 0, 0, 0, NS, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MOCS_62 , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_L3_EVICTION , 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROCEDURAL_TEXTURE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNCACHED , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
// Tiled Resource
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_DEPTH_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_HIZ , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_MCS , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_CCS , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_UAV , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UAV , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER_L3_COHERENT_UC , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER_L3_CACHED , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OGL_WSTN_VERTEX_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POSH_VERTEX_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WDDM_HISTORY_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SAVE_RESTORE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PTBR_PAGE_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PTBR_BATCH_BUFFER , 0 , 0 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0);
//
// CM USAGES
//
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_SurfaceState, 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_L3_SurfaceState, 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_ELLC_SurfaceState, 0 , 0 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_SurfaceState, 0 , 1 , 1 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_ELLC_SurfaceState, 1 , 0 , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_L3_SurfaceState, 0 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_ELLC_L3_SurfaceState, 1 , 0 , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_CACHE_SurfaceState, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
//
// MP USAGES
//
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_BEGIN, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_DEFAULT, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_SurfaceState, 1 , EDRAM, 1 , 0 , 1, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_AGE3_SurfaceState, 1 , EDRAM, 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_END, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
// MHW - SFC
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_AvsLineBufferSurface, 1 , EDRAM, 1 , 0 , 1, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_IefLineBufferSurface, 1 , EDRAM, 1 , 0 , 1, 0, 0, 0, 0, 0, 0);
//Media GMM Resource USAGES
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POST_DEBLOCKING_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_ENCODE , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_DECODE , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAMOUT_DATA_CODEC , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INTRA_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_REFERENCE_PICTURE_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_STATUS_BUFFER_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_MV_OBJECT_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFD_INDIRECT_IT_COEF_OBJECT_DECODE , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFC_INDIRECT_PAKBASE_OBJECT_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BSDMPC_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MPR_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BITPLANE_READ_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_AACSBIT_VECTOR_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_CURR_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_REF_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_DST , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PAK_OBJECT_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_ROW_STORE_BUFFER_CODEC , 1 , 0 , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_STREAMIN_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MV_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_STATUS_ERROR_CODEC , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_LCU_ILDB_STREAMOUT_CODEC , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_SEGMENT_ID_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_HVD_ROWSTORE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_ILDB_STREAM_OUT_BUFFER_CODEC , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SSE_SRC_PIXEL_ROW_STORE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SLICE_STATE_STREAM_OUT_BUFFER_CODEC , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CABAC_SYNTAX_STREAM_OUT_BUFFER_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRED_COL_STORE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_UNCACHED , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_ONLY , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_ONLY , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_L3 , 1 , EDRAM , 1 , 0 , 3, 0 , 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SOFTWARE_SCOREBOARD_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_4XME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_INTRA_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MB_STATS_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PAK_STATS_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PIC_STATE_READ_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PIC_STATE_WRITE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_COMBINED_ENC_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_CONSTANT_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_INTERMEDIATE_CU_RECORD_SURFACE_ENCODE , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SCRATCH_ENCODE , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_LCU_LEVEL_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_HISTORY_INPUT_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_HISTORY_OUTPUT_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_DEBUG_ENCODE , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CONSTANT_TABLE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CU_RECORD_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_MV_TEMPORAL_BUFFER_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CU_PACKET_FOR_PAK_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_BCOMBINED1_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_BCOMBINED2_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_FRAME_STATS_STREAMOUT_DATA_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_TILE_LINE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_TILE_COLUMN_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_TILE_LINE_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_TILE_COLUMN_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_TILE_LINE_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_TILE_COLUMN_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_COUNTER_BUFFER_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HUC_VIRTUAL_ADDR_REGION_BUFFER_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SIZE_STREAMOUT_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMPRESSED_HEADER_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROBABILITY_DELTA_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MAD_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PAK_IMAGESTATE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_BRC_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MB_BRC_CONST_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_MB_QP_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ROI_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBDISABLE_SKIPMAP_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SLICE_MAP_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_WP_DOWNSAMPLED_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_VDENC_IMAGESTATE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0);
/**********************************************************************************/
//
// OCL Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CONST , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CSR_UC , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED , 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_IMAGE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST_HDC , 1 , 1 , 1, 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SCRATCH , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRIVATE_MEM , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRINTF_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_STATE_HEAP_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER_CACHELINE_MISALIGNED , 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_ISH_HEAP_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TAG_MEMORY_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TEXTURE_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SELF_SNOOP_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 3, 0);
/**********************************************************************************/
// Cross Adapter
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
/**********************************************************************************/
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CAMERA_CAPTURE , CAM$, 0 , 0 , 0 , CAM$ , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMMAND_STREAMER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
// Uncacheable copies
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_SOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_DEST , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0);
#include "GmmCachePolicyUndefineConditionals.h"

View File

@ -0,0 +1,678 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmCachePolicy.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen10.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen11.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen12.h"
//=============================================================================
//
// Function: IsSpecialMOCSUsage
//
// Desc: This function returns special(hw-reserved) MocsIdx based on usage
//
// Parameters: usage -> Resource usage type
// UpdateMOCS -> True if MOCS Table must be updated, ow false
//
// Return: int32_t
//
//-----------------------------------------------------------------------------
int32_t GmmLib::GmmGen12CachePolicy::IsSpecialMOCSUsage(GMM_RESOURCE_USAGE_TYPE Usage, bool &UpdateMOCS)
{
int32_t MocsIdx = -1;
UpdateMOCS = true;
//Macros for L3-Eviction Type
#define NA 0x0
#define RO 0x1
#define RW 0x2
#define SP 0x3
switch(Usage)
{
case GMM_RESOURCE_USAGE_CCS:
__GMM_ASSERT(pCachePolicy[Usage].L3 == 0); //Architecturally, CCS isn't L3-cacheable.
pCachePolicy[Usage].L3 = 0;
MocsIdx = 60;
break;
case GMM_RESOURCE_USAGE_MOCS_62:
__GMM_ASSERT(pCachePolicy[Usage].L3 == 0); //Architecturally, TR/Aux-TT node isn't L3-cacheable.
pCachePolicy[Usage].L3 = 0;
MocsIdx = 62;
break;
case GMM_RESOURCE_USAGE_L3_EVICTION:
__GMM_ASSERT(pCachePolicy[Usage].L3 == 0 &&
pCachePolicy[Usage].L3Eviction == RW); //Reserved MOCS for L3-evictions
pCachePolicy[Usage].L3 = 0;
pCachePolicy[Usage].L3Eviction = RW;
MocsIdx = 63;
break;
case GMM_RESOURCE_USAGE_L3_EVICTION_SPECIAL:
case GMM_RESOURCE_USAGE_CCS_MEDIA_WRITABLE:
__GMM_ASSERT(pCachePolicy[Usage].L3 &&
pCachePolicy[Usage].L3Eviction == SP); //Reserved MOCS for L3-evictions
//Special-case for Displayable, and similar non-LLC accesses
GMM_ASSERTDPF(pCachePolicy[Usage].LLC == 0, "MOCS#61's Special Eviction isn't for LLC caching");
pCachePolicy[Usage].L3 = 1;
pCachePolicy[Usage].L3Eviction = SP;
MocsIdx = 61;
break;
default:
UpdateMOCS = false;
break;
}
if(pCachePolicy[Usage].L3Eviction == RW)
{
GMM_CACHE_POLICY_ELEMENT L3Eviction;
L3Eviction.Value = pCachePolicy[GMM_RESOURCE_USAGE_L3_EVICTION].Value;
//For internal purpose, hw overrides MOCS#63 as L3-uncacheable, still using it for L3-evictions
if(Usage != GMM_RESOURCE_USAGE_L3_EVICTION)
{
L3Eviction.L3 = 1; //Override L3, to verify MOCS#63 applicable or not
}
__GMM_ASSERT(pCachePolicy[Usage].Value == L3Eviction.Value); //Allow mis-match due to override registries
//MocsIdx = 63; //Use non-#63 MOCS, #63 itself is L3-uncached
}
else if(pCachePolicy[Usage].L3Eviction == SP)
{
__GMM_ASSERT(pCachePolicy[Usage].Value == pCachePolicy[GMM_RESOURCE_USAGE_L3_EVICTION_SPECIAL].Value); //Allow mis-match due to override registries
MocsIdx = 61;
}
return MocsIdx;
}
//=============================================================================
//
// Function: __GmmGen12InitCachePolicy
//
// Desc: This function initializes the cache policy
//
// Parameters: pCachePolicy -> Ptr to array to be populated with the
// mapping of usages -> cache settings.
//
// Return: GMM_STATUS
//
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::GmmGen12CachePolicy::InitCachePolicy()
{
__GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
#define DEFINE_CACHE_ELEMENT(usage, llc, ellc, l3, wt, age, aom, lecc_scc, l3_scc, scf, sso, cos, hdcl1, l3evict) DEFINE_CP_ELEMENT(usage, llc, ellc, l3, wt, age, aom, lecc_scc, l3_scc, scf, sso, cos, hdcl1, l3evict, 0, 0, 0, 0)
#include "GmmGen12CachePolicy.h"
#define TC_LLC (1)
#define TC_ELLC (0)
#define TC_LLC_ELLC (2)
#define LeCC_UNCACHEABLE (0x0)
#define LeCC_WC_UNCACHEABLE (0x1)
#define LeCC_WT_CACHEABLE (0x2) //Only used as MemPushWRite disqualifier if set along with eLLC-only -still holds on gen12+?
#define LeCC_WB_CACHEABLE (0x3)
#define L3_UNCACHEABLE (0x1)
#define L3_WB_CACHEABLE (0x3)
#define DISABLE_SKIP_CACHING_CONTROL (0x0)
#define ENABLE_SKIP_CACHING_CONTROL (0x1)
#define DISABLE_SELF_SNOOP_OVERRIDE (0x0)
#define ENABLE_SELF_SNOOP_OVERRIDE (0x1)
#define ENABLE_SELF_SNOOP_ALWAYS (0x3)
#define CLASS_SERVICE_ZERO (0x0)
{
SetUpMOCSTable();
}
{
// Define index of cache element
uint32_t Usage = 0;
#if(_WIN32 && (_DEBUG || _RELEASE_INTERNAL))
void *pKmdGmmContext = NULL;
OverrideCachePolicy(pKmdGmmContext);
#endif
// Process the cache policy and fill in the look up table
for(; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
bool CachePolicyError = false;
bool SpecialMOCS = false;
int32_t CPTblIdx = -1;
uint32_t j = 0;
uint64_t PTEValue = 0;
GMM_CACHE_POLICY_TBL_ELEMENT UsageEle = {0};
CPTblIdx = IsSpecialMOCSUsage((GMM_RESOURCE_USAGE_TYPE)Usage, SpecialMOCS);
UsageEle.LeCC.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned LeCC.DwordValue.
UsageEle.LeCC.SelfSnoop = DISABLE_SELF_SNOOP_OVERRIDE;
UsageEle.LeCC.CoS = CLASS_SERVICE_ZERO;
UsageEle.LeCC.SCC = 0;
UsageEle.LeCC.ESC = 0;
if(pCachePolicy[Usage].SCF && pGmmLibContext->GetSkuTable().FtrLLCBypass)
{
UsageEle.LeCC.SCF = pCachePolicy[Usage].SCF;
__GMM_ASSERT(pCachePolicy[Usage].LLC == 0); //LLC and ByPassLLC are mutually-exclusive
}
if(pCachePolicy[Usage].SSO & ENABLE_SELF_SNOOP_OVERRIDE)
{
UsageEle.LeCC.SelfSnoop = pCachePolicy[Usage].SSO & ENABLE_SELF_SNOOP_ALWAYS;
}
if(pCachePolicy[Usage].CoS)
{
UsageEle.LeCC.CoS = pCachePolicy[Usage].CoS;
}
if(pCachePolicy[Usage].HDCL1)
{
UsageEle.HDCL1 = 1;
}
if(pCachePolicy[Usage].LeCC_SCC)
{
UsageEle.LeCC.SCC = pCachePolicy[Usage].LeCC_SCC;
UsageEle.LeCC.ESC = ENABLE_SKIP_CACHING_CONTROL;
}
UsageEle.LeCC.LRUM = pCachePolicy[Usage].AGE;
// default to LLC target cache.
UsageEle.LeCC.TargetCache = TC_LLC;
UsageEle.LeCC.Cacheability = LeCC_WB_CACHEABLE;
if(pCachePolicy[Usage].LLC)
{
UsageEle.LeCC.TargetCache = TC_LLC;
__GMM_ASSERT(pCachePolicy[Usage].SCF == 0); //LLC and ByPassLLC are mutually-exclusive
}
else
{
UsageEle.LeCC.Cacheability = LeCC_WC_UNCACHEABLE;
}
UsageEle.L3.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned L3.UshortValue.
UsageEle.L3.ESC = DISABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = 0;
UsageEle.L3.Cacheability = pCachePolicy[Usage].L3 ? L3_WB_CACHEABLE : L3_UNCACHEABLE;
__GMM_ASSERT((pCachePolicy[Usage].L3 && pCachePolicy[Usage].L3Eviction != 0) ||
(pCachePolicy[Usage].L3 == 0 && (pCachePolicy[Usage].L3Eviction == 0 || Usage == GMM_RESOURCE_USAGE_L3_EVICTION)));
if(pCachePolicy[Usage].L3_SCC)
{
UsageEle.L3.ESC = ENABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = (uint16_t)pCachePolicy[Usage].L3_SCC;
}
//Special-case MOCS handling for MOCS Table Index 60-63
if(CPTblIdx >= GMM_GEN12_MAX_NUMBER_MOCS_INDEXES)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[CPTblIdx];
if(SpecialMOCS &&
!(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
TblEle->L3.UshortValue == UsageEle.L3.UshortValue &&
TblEle->HDCL1 == UsageEle.HDCL1))
{
//Assert if being overwritten!
__GMM_ASSERT(TblEle->LeCC.DwordValue == 0 &&
TblEle->L3.UshortValue == 0 &&
TblEle->HDCL1 == 0);
#if(_WIN32 && (_DEBUG || _RELEASE_INTERNAL))
if(pCachePolicy[Usage].IsOverridenByRegkey)
{
TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
TblEle->L3.UshortValue = UsageEle.L3.UshortValue;
TblEle->HDCL1 = UsageEle.HDCL1;
}
#endif
}
}
//For HDC L1 caching, MOCS Table index 48-59 should be used
else if(UsageEle.HDCL1)
{
for(j = GMM_GEN10_HDCL1_MOCS_INDEX_START; j <= CurrentMaxL1HdcMocsIndex; j++)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[j];
if(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
TblEle->L3.UshortValue == UsageEle.L3.UshortValue &&
TblEle->HDCL1 == UsageEle.HDCL1)
{
CPTblIdx = j;
break;
}
}
}
else
{
// Due to unstable system behavior on TGLLP, MOCS #0 index had to be programmed as UC in MOCS lookup table - pCachePolicyTlbElement
// But still Index 0 is Reserved for Error by HW and should not be used.
// Hence Gmmlib will opt out from the MOCS#0 usage and Lookup into MOCS table and MOCS index assigment must start from Index 1.
for(j = 1; j <= CurrentMaxMocsIndex; j++)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[j];
if(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
TblEle->L3.UshortValue == UsageEle.L3.UshortValue &&
TblEle->HDCL1 == UsageEle.HDCL1)
{
CPTblIdx = j;
break;
}
}
}
// Didn't find the caching settings in one of the already programmed lookup table entries.
// Need to add a new lookup table entry.
if(CPTblIdx == -1)
{
#if(_WIN32 && (_DEBUG || _RELEASE_INTERNAL))
// If the Cache Policy setting is overriden through regkey,
// don't raise an assert/log error. Raising an assert for debug/perf testing isn't really helpful
if(pCachePolicy[Usage].IsOverridenByRegkey)
{
if(UsageEle.HDCL1 && CurrentMaxL1HdcMocsIndex < GMM_GEN12_MAX_NUMBER_MOCS_INDEXES - 1)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &(pGmmLibContext->GetCachePolicyTlbElement()[++CurrentMaxL1HdcMocsIndex]);
CPTblIdx = CurrentMaxL1HdcMocsIndex;
TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
TblEle->L3.UshortValue = UsageEle.L3.UshortValue;
TblEle->HDCL1 = UsageEle.HDCL1;
}
else if(CurrentMaxMocsIndex < GMM_GEN10_HDCL1_MOCS_INDEX_START)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &(pGmmLibContext->GetCachePolicyTlbElement()[++CurrentMaxMocsIndex]);
CPTblIdx = CurrentMaxMocsIndex;
TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
TblEle->L3.UshortValue = UsageEle.L3.UshortValue;
TblEle->HDCL1 = UsageEle.HDCL1;
}
else
{
// Too many unique caching combinations to program the
// MOCS lookup table.
CachePolicyError = true;
GMM_ASSERTDPF(
"Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
"(we only support GMM_GEN_MAX_NUMBER_MOCS_INDEXES = %d)",
GMM_MAX_NUMBER_MOCS_INDEXES - 1);
// Set cache policy index to uncached.
CPTblIdx = 3;
}
}
else
#endif
{
GMM_ASSERTDPF(false, "CRITICAL ERROR: Cache Policy Usage value specified by Client is not defined in Fixed MOCS Table!");
CachePolicyError = true;
GMM_ASSERTDPF(
"Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
"(we only support GMM_GEN_MAX_NUMBER_MOCS_INDEXES = %d)",
CurrentMaxMocsIndex);
// Set cache policy index to uncached.
CPTblIdx = 3;
}
}
// PTE entries do not control caching on SKL+ (for legacy context)
if(!GetUsagePTEValue(pCachePolicy[Usage], Usage, &PTEValue))
{
CachePolicyError = true;
}
pCachePolicy[Usage].PTE.DwordValue = PTEValue & 0xFFFFFFFF;
pCachePolicy[Usage].PTE.HighDwordValue = 0;
pCachePolicy[Usage].MemoryObjectOverride.Gen12.Index = CPTblIdx;
pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
if(CachePolicyError)
{
GMM_ASSERTDPF("Cache Policy Init Error: Invalid Cache Programming - Element %d", Usage);
}
}
}
return GMM_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Return true if (MT2) is a better match for (WantedMT)
/// than (MT1)
///
/// @param[in] WantedMT: Wanted Memory Type
/// @param[in] MT1: Memory Type for PATIdx1
/// @param[in] MT2: Memory Type for PATIdx2
///
/// @return Select the new PAT Index True/False
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::GmmGen12CachePolicy::SelectNewPATIdx(GMM_GFX_MEMORY_TYPE WantedMT,
GMM_GFX_MEMORY_TYPE MT1, GMM_GFX_MEMORY_TYPE MT2)
{
uint8_t SelectPAT2 = 0;
// select on Memory Type
if(MT1 != WantedMT)
{
if(MT2 == WantedMT || MT2 == GMM_GFX_UC_WITH_FENCE)
{
SelectPAT2 = 1;
}
goto EXIT;
}
EXIT:
return SelectPAT2;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the PAT idx that best matches the cache policy for this usage.
///
/// @param: CachePolicy: cache policy for a usage
///
/// @return PAT Idx to use in the PTE
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmGen12CachePolicy::BestMatchingPATIdx(GMM_CACHE_POLICY_ELEMENT CachePolicy)
{
uint32_t i;
uint32_t PATIdx = 0;
GMM_GFX_MEMORY_TYPE WantedMemoryType = GMM_GFX_UC_WITH_FENCE, MemoryType;
WA_TABLE * pWaTable = &const_cast<WA_TABLE &>(pGmmLibContext->GetWaTable());
WantedMemoryType = GetWantedMemoryType(CachePolicy);
// Override wantedMemoryType so that PAT.MT is UC
// Gen12 uses max function to resolve PAT-vs-MOCS MemType, So unless PTE.PAT says UC, MOCS won't be able to set UC!
if(pWaTable->WaMemTypeIsMaxOfPatAndMocs)
{
WantedMemoryType = GMM_GFX_UC_WITH_FENCE;
}
for(i = 1; i < GMM_NUM_PAT_ENTRIES; i++)
{
GMM_PRIVATE_PAT PAT1 = GetPrivatePATEntry(PATIdx);
GMM_PRIVATE_PAT PAT2 = GetPrivatePATEntry(i);
if(SelectNewPATIdx(WantedMemoryType,
(GMM_GFX_MEMORY_TYPE)PAT1.Gen12.MemoryType,
(GMM_GFX_MEMORY_TYPE)PAT2.Gen12.MemoryType))
{
PATIdx = i;
}
}
MemoryType = (GMM_GFX_MEMORY_TYPE)GetPrivatePATEntry(PATIdx).Gen12.MemoryType;
if(MemoryType != WantedMemoryType)
{
// Failed to find a matching PAT entry
return GMM_PAT_ERROR;
}
return PATIdx;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Initializes WA's needed for setting up the Private PATs
/// WaNoMocsEllcOnly (reset)
/// WaGttPat0, WaGttPat0GttWbOverOsIommuEllcOnly, WaGttPat0WB (use from base class)
///
/// @return GMM_STATUS
///
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmGen12CachePolicy::SetPATInitWA()
{
GMM_STATUS Status = GMM_SUCCESS;
WA_TABLE * pWaTable = &const_cast<WA_TABLE &>(pGmmLibContext->GetWaTable());
#if(defined(__GMM_KMD__))
__GMM_ASSERT(pGmmLibContext->GetSkuTable().FtrMemTypeMocsDeferPAT == 0x0); //MOCS.TargetCache supports eLLC only, PAT.TC -> reserved bits.
pWaTable->WaGttPat0WB = 0; //Override PAT #0
#else
Status = GMM_ERROR;
#endif
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Initializes the Gfx PAT tables for AdvCtx and Gfx MMIO/Private PAT
/// PAT0 = WB_COHERENT or UC depending on WaGttPat0WB
/// PAT1 = UC or WB_COHERENT depending on WaGttPat0WB
/// PAT2 = WB_MOCSLESS
/// PAT3 = WB
/// PAT4 = WT
/// PAT5 = WC
/// PAT6 = WC
/// PAT7 = WC
/// HLD says to set to PAT0/1 to WC, but since we don't have a WC in GPU,
/// WC option is same as UC. Hence setting PAT0 or PAT1 to UC.
/// Unused PAT's (5,6,7) are set to WC.
///
/// @return GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmGen12CachePolicy::SetupPAT()
{
GMM_STATUS Status = GMM_SUCCESS;
#if(defined(__GMM_KMD__))
uint32_t i = 0;
GMM_GFX_MEMORY_TYPE GfxMemType = GMM_GFX_UC_WITH_FENCE;
int32_t * pPrivatePATTableMemoryType = NULL;
pPrivatePATTableMemoryType = pGmmLibContext->GetPrivatePATTableMemoryType();
__GMM_ASSERT(pGmmLibContext->GetSkuTable().FtrIA32eGfxPTEs);
for(i = 0; i < GMM_NUM_GFX_PAT_TYPES; i++)
{
pPrivatePATTableMemoryType[i] = -1;
}
// Set values for GmmGlobalInfo PrivatePATTable
for(i = 0; i < GMM_NUM_PAT_ENTRIES; i++)
{
GMM_PRIVATE_PAT PAT = {0};
switch(i)
{
case PAT0:
if(pGmmLibContext->GetWaTable().WaGttPat0)
{
if(pGmmLibContext->GetWaTable().WaGttPat0WB)
{
GfxMemType = GMM_GFX_WB;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
}
else
{
GfxMemType = GMM_GFX_UC_WITH_FENCE;
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT0;
}
}
else // if GTT is not tied to PAT0 then WaGttPat0WB is NA
{
GfxMemType = GMM_GFX_WB;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
}
break;
case PAT1:
if(pGmmLibContext->GetWaTable().WaGttPat0 && !pGmmLibContext->GetWaTable().WaGttPat0WB)
{
GfxMemType = GMM_GFX_WB;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT1;
}
else
{
GfxMemType = GMM_GFX_UC_WITH_FENCE;
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT1;
}
break;
case PAT2:
// This PAT idx shall be used for MOCS'Less resources like Page Tables
// Page Tables have TC hardcoded to eLLC+LLC in Adv Ctxt. Hence making this to have same in Leg Ctxt.
// For BDW-H, due to Perf issue, TC has to be eLLC only for Page Tables when eDRAM is present.
GfxMemType = GMM_GFX_WB;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_MOCSLESS] = PAT2;
break;
case PAT3:
GfxMemType = GMM_GFX_WB;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB] = PAT3;
break;
case PAT4:
GfxMemType = GMM_GFX_WT;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WT] = PAT4;
break;
case PAT5:
case PAT6:
case PAT7:
GfxMemType = GMM_GFX_WC;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WC] = PAT5;
break;
default:
__GMM_ASSERT(0);
Status = GMM_ERROR;
}
PAT.Gen12.MemoryType = GfxMemType;
SetPrivatePATEntry(i, PAT);
}
#else
Status = GMM_ERROR;
#endif
return Status;
}
//=============================================================================
//
// Function: SetUpMOCSTable
//
// Desc:
//
// Parameters:
//
// Return: GMM_STATUS
//
//-----------------------------------------------------------------------------
void GmmLib::GmmGen12CachePolicy::SetUpMOCSTable()
{
GMM_CACHE_POLICY_TBL_ELEMENT *pCachePolicyTlbElement = &(pGmmLibContext->GetCachePolicyTlbElement()[0]);
#define GMM_DEFINE_MOCS(Index, L3_ESC, L3_SCC, L3_CC, LeCC_CC, LeCC_TC, LeCC_LRUM, LeCC_AOM, LeCC_ESC, LeCC_SCC, LeCC_PFM, LeCC_SCF, LeCC_CoS, LeCC_SelfSnoop, _HDCL1) \
{ \
pCachePolicyTlbElement[Index].L3.ESC = L3_ESC; \
pCachePolicyTlbElement[Index].L3.SCC = L3_SCC; \
pCachePolicyTlbElement[Index].L3.Cacheability = L3_CC; \
pCachePolicyTlbElement[Index].LeCC.Cacheability = LeCC_CC; \
pCachePolicyTlbElement[Index].LeCC.TargetCache = LeCC_TC; \
pCachePolicyTlbElement[Index].LeCC.LRUM = LeCC_LRUM; \
pCachePolicyTlbElement[Index].LeCC.AOM = LeCC_AOM; \
pCachePolicyTlbElement[Index].LeCC.ESC = LeCC_ESC; \
pCachePolicyTlbElement[Index].LeCC.SCC = LeCC_SCC; \
pCachePolicyTlbElement[Index].LeCC.PFM = LeCC_PFM; \
pCachePolicyTlbElement[Index].LeCC.SCF = LeCC_SCF; \
pCachePolicyTlbElement[Index].LeCC.CoS = LeCC_CoS; \
pCachePolicyTlbElement[Index].LeCC.SelfSnoop = LeCC_SelfSnoop; \
pCachePolicyTlbElement[Index].HDCL1 = _HDCL1; \
}
// clang-format off
//Default MOCS Table
for(int index = 0; index < GMM_MAX_NUMBER_MOCS_INDEXES; index++)
{ // Index ES SCC L3CC LeCC TC LRUM DAoM ERSC SCC PFM SCF CoS SSE HDCL1
GMM_DEFINE_MOCS( index , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
}
// Fixed MOCS Table
// Index ESC SCC L3CC LeCC TC LRUM DAoM ERSC SCC PFM SCF CoS SSE HDCL1
GMM_DEFINE_MOCS( 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 2 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 3 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 4 , 0 , 0 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 5 , 0 , 0 , 1 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 6 , 0 , 0 , 1 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 7 , 0 , 0 , 3 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 8 , 0 , 0 , 1 , 3 , 1 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 9 , 0 , 0 , 3 , 3 , 1 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 10 , 0 , 0 , 1 , 3 , 1 , 3 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 11 , 0 , 0 , 3 , 3 , 1 , 3 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 12 , 0 , 0 , 1 , 3 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 13 , 0 , 0 , 3 , 3 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 14 , 0 , 0 , 1 , 3 , 1 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 15 , 0 , 0 , 3 , 3 , 1 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 16 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 17 , 0 , 0 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 18 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 0 )
GMM_DEFINE_MOCS( 19 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 7 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 20 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 3 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 21 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 22 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 1 , 3 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 23 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 1 , 7 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 48 , 0 , 0 , 3 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 )
GMM_DEFINE_MOCS( 49 , 0 , 0 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 )
GMM_DEFINE_MOCS( 50 , 0 , 0 , 1 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 )
GMM_DEFINE_MOCS( 51 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 )
GMM_DEFINE_MOCS( 60 , 0 , 0 , 1 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 61 , 0 , 0 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 62 , 0 , 0 , 1 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 63 , 0 , 0 , 1 , 3 , 1 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
if(!pGmmLibContext->GetSkuTable().FtrLLCBypass ||
GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_ROCKETLAKE)
{
GMM_DEFINE_MOCS( 16 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 17 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 61 , 0 , 0 , 3 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
}
// clang-format on
CurrentMaxMocsIndex = 23;
CurrentMaxL1HdcMocsIndex = 51;
CurrentMaxSpecialMocsIndex = 63;
#undef GMM_DEFINE_MOCS
}

View File

@ -0,0 +1,314 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmCachePolicyConditionals.h"
#define EDRAM (SKU(FtrEDram))
#define FBLLC (SKU(FtrFrameBufferLLC))
#define NS (SKU(FtrLLCBypass))
//Macros for L3-Eviction Type
#define NA 0x0
#define RO 0x1
#define RW 0x2
#define SP 0x3
// Cache Policy Definition
// AOM = Do not allocate on miss (0 = allocate on miss [normal cache behavior], 1 = don't allocate on miss)
// LeCC_SCC = LLC/eLLC skip caching control (disabled if LeCC_SCC = 0)
// L3_SCC = L3 skip caching control (disabled if L3_SCC = 0)
// SCF = Snoop Control Field (SCF)- Only for SKL/BXT and Gen12+ (as coherent/non-coherent)
// SSO = Override MIDI self snoop settings (1 = never send to uncore, 3 = always send to uncore, 0 = [default] No override )
// CoS = Class of Service ( allowed values 1, 2, 3 for class IDs 1, 2, 3 respectively, default class 0)
// HDCL1 = HDC L1 cache control (1 = cached in HDC L1, 0 = not cached in HDC L1)
// Faster PushWrite(Gen10+) used iff !WT, eLLC-only cacheable - Globally visible surface (eg display surface) should be marked WT
// L3Evict = Type of L3-eviction (0= NA ie not L3 cacheable, 1= RO ie ReadOnly, 2 = RW ie Standard using MOCS#63), 3 = SP ie Special using MOCS#61 for non-LLC access)
//***************************************************************************************************************/
// USAGE TYPE , LLC , ELLC , L3 , WT , AGE , AOM , LeCC_SCC , L3_SCC, SCF, SSO, CoS, HDCL1, L3Evict)
/****************************************************************************************************************/
// KMD Usages
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMP_FRAME_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SWITCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CURSOR , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAY_STATIC_IMG_FOR_SMOOTH_ROTATION_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DUMMY_PAGE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GDI_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GENERIC_KMD_RESOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
// GMM_RESOURCE_USAGE_GFX_RING is only used if WaEnableRingHostMapping is enabled.
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GFX_RING , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GTT_TRANSFER_REGION , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HW_CONTEXT , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATE_MANAGER_KERNEL_STATE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_STAGING_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBM_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_NNDI_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OVERLAY_MBM , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRIMARY_SURFACE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, NS, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SCREEN_PROTECTION_INTERMEDIATE_SURFACE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADOW_SURFACE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SM_SCRATCH_STATE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATUS_PAGE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TIMER_PERF_QUEUE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNKNOWN , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNMAP_PAGING_RESERVED_GTT_DMA_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VSC_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WA_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_OCA_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
//
// 3D Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UMD_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BINDING_TABLE_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CCS , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONSTANT_BUFFER_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEPTH_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAYABLE_RENDER_TARGET , 0 , EDRAM, 1 , EDRAM , 0 , 0, 0, 0, NS, 0, 0, 0, SP );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GATHER_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_SURFACE_STATE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_DYNAMIC_STATE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE_UC , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT_L1_CACHED , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INDIRECT_OBJECT , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INSTRUCTION , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HIZ , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER_L3_COHERENT_UC , 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER_L3_CACHED , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MCS , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PUSH_CONSTANT_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PULL_CONSTANT_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 1, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_QUERY , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE , 0 , 1 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STAGING , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STENCIL_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAM_OUTPUT_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE_LLC_BYPASS , 0 , 1 , 1 , 0 , 0 , 0, 0, 0, NS, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MOCS_62 , 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_L3_EVICTION , 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RW );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_L3_EVICTION_SPECIAL , 0 , EDRAM, 1 , EDRAM , 0 , 0, 0, 0, NS, 0, 0, 0, SP );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROCEDURAL_TEXTURE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
// Tiled Resource
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_DEPTH_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_HIZ , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_MCS , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_CCS , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 1, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 1, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_UAV , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UAV , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER_L3_COHERENT_UC , 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER_L3_CACHED , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OGL_WSTN_VERTEX_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POSH_VERTEX_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WDDM_HISTORY_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SAVE_RESTORE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PTBR_PAGE_POOL , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PTBR_BATCH_BUFFER , 0 , 0 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, RO );
//
// CM USAGES
//
// USAGE TYPE , LLC , ELLC , L3 , WT , AGE , AOM , LeCC_SCC , L3_SCC, SCF, SSO, CoS, HDCL1, L3Evict )
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_SurfaceState, 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_StateHeap, 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_L1_Enabled_SurfaceState, 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 1, RO );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_L3_SurfaceState, 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_ELLC_SurfaceState, 0 , 0 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_SurfaceState, 0 , 1 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_ELLC_SurfaceState, 1 , 0 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_L3_SurfaceState, 0 , 1 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_ELLC_L3_SurfaceState, 1 , 0 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_CACHE_SurfaceState, 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
//
// MP USAGES
//
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_BEGIN, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_DEFAULT, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_SurfaceState, 1 , 1 , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_END, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
// MHW - SFC
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface, 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_AvsLineBufferSurface, 1 , 1 , 1 , 0 , 1, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_IefLineBufferSurface, 1 , 1 , 1 , 0 , 1, 0, 0, 0, 0, 0, 0, 0, RO );
//Media GMM Resource USAGES
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POST_DEBLOCKING_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_ENCODE , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_DECODE , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAMOUT_DATA_CODEC , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INTRA_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_REFERENCE_PICTURE_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_STATUS_BUFFER_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_MV_OBJECT_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFD_INDIRECT_IT_COEF_OBJECT_DECODE , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFC_INDIRECT_PAKBASE_OBJECT_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BSDMPC_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MPR_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BITPLANE_READ_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_AACSBIT_VECTOR_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC , 0 , EDRAM , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_CURR_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_REF_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_DST , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PAK_OBJECT_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_ROW_STORE_BUFFER_CODEC , 1 , 0 , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_STREAMIN_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MV_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_STATUS_ERROR_CODEC , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_LCU_ILDB_STREAMOUT_CODEC , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_SEGMENT_ID_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_HVD_ROWSTORE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_ILDB_STREAM_OUT_BUFFER_CODEC , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SSE_SRC_PIXEL_ROW_STORE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SLICE_STATE_STREAM_OUT_BUFFER_CODEC , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CABAC_SYNTAX_STREAM_OUT_BUFFER_CODEC , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRED_COL_STORE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_UNCACHED , 0 , 0 , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_ONLY , 0 , EDRAM , 0 , 0 , 0, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_ONLY , 1 , EDRAM , 0 , 0 , 3, 0 , 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_L3 , 1 , EDRAM , 1 , 0 , 3, 0 , 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CCS_MEDIA_WRITABLE , 0 , EDRAM , 1 , EDRAM , 0, 0, 0, 0, NS, 0, 0, 0, SP );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SOFTWARE_SCOREBOARD_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_4XME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_INTRA_DISTORTION_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MB_STATS_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PAK_STATS_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PIC_STATE_READ_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PIC_STATE_WRITE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_COMBINED_ENC_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_CONSTANT_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_INTERMEDIATE_CU_RECORD_SURFACE_ENCODE , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SCRATCH_ENCODE , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_LCU_LEVEL_DATA_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_HISTORY_INPUT_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_HISTORY_OUTPUT_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_DEBUG_ENCODE , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CONSTANT_TABLE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CU_RECORD_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_MV_TEMPORAL_BUFFER_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CU_PACKET_FOR_PAK_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_BCOMBINED1_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_BCOMBINED2_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_FRAME_STATS_STREAMOUT_DATA_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_TILE_LINE_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_TILE_COLUMN_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_TILE_LINE_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_TILE_COLUMN_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_TILE_LINE_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_TILE_COLUMN_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_COUNTER_BUFFER_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HUC_VIRTUAL_ADDR_REGION_BUFFER_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SIZE_STREAMOUT_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMPRESSED_HEADER_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROBABILITY_DELTA_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_RECORD_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_SIZE_STAS_BUFFER_CODEC , 1 , EDRAM , 0 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MAD_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PAK_IMAGESTATE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_BRC_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MB_BRC_CONST_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_MB_QP_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ROI_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBDISABLE_SKIPMAP_CODEC , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SLICE_MAP_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_WP_DOWNSAMPLED_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_VDENC_IMAGESTATE_ENCODE , 1 , EDRAM , 1 , 0 , 3, 0, 0, 0, 0, 0, 0, 0, RO );
/**********************************************************************************/
//
// OCL Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CONST , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 1, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CSR_UC , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED , 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_IMAGE , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST_HDC , 1 , 1 , 1, 0 , 3 , 0, 0, 0, 0, 0, 0, 1, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SCRATCH , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRIVATE_MEM , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRINTF_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_STATE_HEAP_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER_CACHELINE_MISALIGNED , 1 , 1 , 0 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_ISH_HEAP_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TAG_MEMORY_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TEXTURE_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 0, 0, 0, RO );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SELF_SNOOP_BUFFER , 1 , 1 , 1 , 0 , 3 , 0, 0, 0, 0, 3, 0, 0, RO );
/**********************************************************************************/
// Cross Adapter
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
/**********************************************************************************/
// BCS
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_BLT_SOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_BLT_DESTINATION , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
/**********************************************************************************/
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CAMERA_CAPTURE , CAM$, 0 , 0 , 0 , CAM$ , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_NULL_CONTEXT_BB , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMMAND_STREAMER , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA );
// Uncacheable copies
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_SOURCE , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_DEST , 0 , 0 , 0 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, NA);
// Shader resource uncachable, needed for WA_18013889147
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE_L1_NOT_CACHED , 0 , 1 , 1 , 0 , 0 , 0, 0, 0, 0, 0, 0, 0, RO );
#include "GmmCachePolicyUndefineConditionals.h"

View File

@ -0,0 +1,417 @@
/*==============================================================================
Copyright(c) 2020 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmCachePolicy.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen10.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen11.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen12.h"
#include "External/Common/CachePolicy/GmmCachePolicyGen12dGPU.h"
//=============================================================================
//
// Function: IsSpecialMOCSUsage
//
// Desc: This function returns special(hw-reserved) MocsIdx based on usage
//
// Parameters: usage -> Resource usage type
// UpdateMOCS -> True if MOCS Table must be updated, ow false
//
// Return: int32_t
//
//-----------------------------------------------------------------------------
int32_t GmmLib::GmmGen12dGPUCachePolicy::IsSpecialMOCSUsage(GMM_RESOURCE_USAGE_TYPE Usage, bool &UpdateMOCS)
{
int32_t MocsIdx = -1;
UpdateMOCS = true;
switch(Usage)
{
case GMM_RESOURCE_USAGE_CCS:
__GMM_ASSERT(pCachePolicy[Usage].L3 == 0 && //Architecturally, CCS isn't L3-cacheable.
pCachePolicy[Usage].UcLookup == 0); // On DG1/XE_HP_SDV/DG2, CCS Resource is never cached in L3, so LookUp is N/A
MocsIdx = 60;
break;
case GMM_RESOURCE_USAGE_MOCS_62:
__GMM_ASSERT(pCachePolicy[Usage].L3 == 0 &&
pCachePolicy[Usage].UcLookup == 0); //Architecturally, TR/Aux-TT node isn't L3-cacheable.
MocsIdx = 62;
break;
case GMM_RESOURCE_USAGE_L3_EVICTION:
MocsIdx = 63;
break;
case GMM_RESOURCE_USAGE_L3_EVICTION_SPECIAL:
case GMM_RESOURCE_USAGE_CCS_MEDIA_WRITABLE:
MocsIdx = 61;
break;
default:
UpdateMOCS = false;
break;
}
return MocsIdx;
}
//=============================================================================
//
// Function: __GmmGen12dGPUInitCachePolicy
//
// Desc: This function initializes the cache policy
//
// Parameters: pCachePolicy -> Ptr to array to be populated with the
// mapping of usages -> cache settings.
//
// Return: GMM_STATUS
//
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::GmmGen12dGPUCachePolicy::InitCachePolicy()
{
__GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
#define DEFINE_CACHE_ELEMENT(usage, l3, l3_scc, hdcl1, go, uclookup, l1cc) DEFINE_CP_ELEMENT(usage, 0, 0, l3, 0, 0, 0, 0, l3_scc, 0, 0, 0, hdcl1, 0, 0, go, uclookup, l1cc)
#include "GmmGen12dGPUCachePolicy.h"
#define L3_UNCACHEABLE (0x1)
#define L3_WB_CACHEABLE (0x3)
#define DISABLE_SKIP_CACHING_CONTROL (0x0)
#define ENABLE_SKIP_CACHING_CONTROL (0x1)
#define DISABLE_SELF_SNOOP_OVERRIDE (0x0)
#define CLASS_SERVICE_ZERO (0x0)
#define GMM_GEN12_MAX_NUMBER_MOCS_INDEXES (60) // On TGL last four (#60-#63) are reserved by h/w, few? are sw configurable though (#60)
{
SetUpMOCSTable();
}
{
// Define index of cache element
uint32_t Usage = 0;
#if(_WIN32 && (_DEBUG || _RELEASE_INTERNAL))
void *pKmdGmmContext = NULL;
OverrideCachePolicy(pKmdGmmContext);
#endif
// Process the cache policy and fill in the look up table
for(; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
bool CachePolicyError = false;
bool SpecialMOCS = false;
int32_t CPTblIdx = -1;
uint32_t j = 0;
uint64_t PTEValue = 0;
GMM_CACHE_POLICY_TBL_ELEMENT UsageEle = {0};
uint32_t StartMocsIdx = 0;
switch(GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform))
{
case IGFX_DG1:
case IGFX_XE_HP_SDV:
case IGFX_PVC:
StartMocsIdx = 1; // Index 0 is reserved for Error
break;
case IGFX_DG2:
// DG2 provides 2 wires for MOCS Registers, gives 4(2^2) indexes to program.
StartMocsIdx = 0;
break;
default:
StartMocsIdx = 1;
break;
}
// No Special MOCS handling for next platform
if(GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) < IGFX_DG2)
{
CPTblIdx = IsSpecialMOCSUsage((GMM_RESOURCE_USAGE_TYPE)Usage, SpecialMOCS);
}
// Applicable upto Xe_HP only
if(pCachePolicy[Usage].HDCL1 &&
(GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) <= IGFX_XE_HP_SDV))
{
UsageEle.HDCL1 = 1;
}
UsageEle.L3.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned L3.UshortValue.
UsageEle.L3.ESC = DISABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = 0;
UsageEle.L3.Cacheability = pCachePolicy[Usage].L3 ? L3_WB_CACHEABLE : L3_UNCACHEABLE;
if(pCachePolicy[Usage].L3_SCC)
{
UsageEle.L3.ESC = ENABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = (uint16_t)pCachePolicy[Usage].L3_SCC;
}
if(GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_PVC)
{
pCachePolicy[Usage].GlbGo = 0;
pCachePolicy[Usage].UcLookup = 0;
}
// Go/Lookup
// N/A for SpecialMOCS
// N/A for DG1, RKL, PVC
// Applicable for IGFX_XE_HP_SDV and DG2 only
if(!SpecialMOCS &&
(FROMPRODUCT(XE_HP_SDV)) &&
(GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) != IGFX_PVC))
{
if(pCachePolicy[Usage].L3 == 0)
{
UsageEle.L3.GlobalGo = pCachePolicy[Usage].GlbGo;
}
UsageEle.L3.UCLookup = pCachePolicy[Usage].UcLookup;
__GMM_ASSERT((pCachePolicy[Usage].UcLookup) || (pCachePolicy[Usage].L3 == 0 && pCachePolicy[Usage].UcLookup == 0));
}
//Special-case MOCS handling for MOCS Table Index 60-63
if(CPTblIdx >= GMM_GEN12_MAX_NUMBER_MOCS_INDEXES)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[CPTblIdx];
if(SpecialMOCS &&
!(TblEle->L3.UshortValue == UsageEle.L3.UshortValue))
{
//Assert if being overwritten!
__GMM_ASSERT(TblEle->L3.UshortValue == 0);
}
}
//For HDC L1 caching, MOCS Table index 48-59 should be used
else if(UsageEle.HDCL1)
{
for(j = GMM_GEN10_HDCL1_MOCS_INDEX_START; j <= CurrentMaxL1HdcMocsIndex; j++)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[j];
if(TblEle->L3.UshortValue == UsageEle.L3.UshortValue &&
TblEle->HDCL1 == UsageEle.HDCL1)
{
CPTblIdx = j;
break;
}
}
}
else
{
for(j = StartMocsIdx; j <= CurrentMaxMocsIndex; j++)
{
if(pCachePolicy[Usage].L3 == 0 &&
pCachePolicy[Usage].GlbGo == 0 &&
pCachePolicy[Usage].UcLookup == 0)
{
CPTblIdx = StartMocsIdx;
break;
}
else
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[j];
if(TblEle->L3.UshortValue == UsageEle.L3.UshortValue)
{
CPTblIdx = j;
break;
}
}
}
}
// Didn't find the caching settings in one of the already programmed lookup table entries.
// Need to add a new lookup table entry.
if(CPTblIdx == -1)
{
{
GMM_ASSERTDPF(false, "CRITICAL ERROR: Cache Policy Usage value specified by Client is not defined in Fixed MOCS Table!");
CachePolicyError = true;
GMM_ASSERTDPF(
"Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
"(we only support GMM_GEN_MAX_NUMBER_MOCS_INDEXES = %d)",
CurrentMaxMocsIndex);
// Set cache policy index to uncached.
CPTblIdx = StartMocsIdx;
}
}
// PTE entries do not control caching on SKL+ (for legacy context)
if(!GetUsagePTEValue(pCachePolicy[Usage], Usage, &PTEValue))
{
CachePolicyError = true;
}
pCachePolicy[Usage].PTE.DwordValue = PTEValue & 0xFFFFFFFF;
pCachePolicy[Usage].PTE.HighDwordValue = 0;
pCachePolicy[Usage].MemoryObjectOverride.Gen12.Index = CPTblIdx;
pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
if(CachePolicyError)
{
GMM_ASSERTDPF("Cache Policy Init Error: Invalid Cache Programming - Element %d", Usage);
}
}
}
return GMM_SUCCESS;
}
#pragma optimize("", on)
//=============================================================================
//
// Function: SetUpMOCSTable
//
// Desc: For Gen12dGPU, Define new Fixed MOCS table
//
// Parameters:
//
// Return: GMM_STATUS
//
//-----------------------------------------------------------------------------
void GmmLib::GmmGen12dGPUCachePolicy::SetUpMOCSTable()
{
GMM_CACHE_POLICY_TBL_ELEMENT *pCachePolicyTlbElement = &(pGmmLibContext->GetCachePolicyTlbElement()[0]);
CurrentMaxL1HdcMocsIndex = 0;
CurrentMaxSpecialMocsIndex = 0;
#define GMM_DEFINE_MOCS(Index, L3_ESC, L3_SCC, L3_CC, L3_Go, L3_LookUp, _HDCL1) \
{ \
pCachePolicyTlbElement[Index].L3.ESC = L3_ESC; \
pCachePolicyTlbElement[Index].L3.SCC = L3_SCC; \
pCachePolicyTlbElement[Index].L3.Cacheability = L3_CC; \
pCachePolicyTlbElement[Index].L3.GlobalGo = L3_Go; \
pCachePolicyTlbElement[Index].L3.UCLookup = L3_LookUp; \
pCachePolicyTlbElement[Index].LeCC.Cacheability = 1; \
pCachePolicyTlbElement[Index].LeCC.TargetCache = 0; \
pCachePolicyTlbElement[Index].LeCC.LRUM = 0; \
pCachePolicyTlbElement[Index].LeCC.AOM = 0; \
pCachePolicyTlbElement[Index].LeCC.ESC = 0; \
pCachePolicyTlbElement[Index].LeCC.SCC = 0; \
pCachePolicyTlbElement[Index].LeCC.PFM = 0; \
pCachePolicyTlbElement[Index].LeCC.SCF = 0; \
pCachePolicyTlbElement[Index].LeCC.CoS = CLASS_SERVICE_ZERO; \
pCachePolicyTlbElement[Index].LeCC.SelfSnoop = DISABLE_SELF_SNOOP_OVERRIDE; \
pCachePolicyTlbElement[Index].HDCL1 = _HDCL1; \
}
// clang-format off
if (GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_DG1)
{
//Default MOCS Table
for(int index = 0; index < GMM_MAX_NUMBER_MOCS_INDEXES; index++)
{ // Index ESC SCC L3CC Go LookUp HDCL1
GMM_DEFINE_MOCS( index , 0 , 0 , 3 , 0 , 0 , 0 )
}
// Fixed MOCS Table
// Index ESC SCC L3CC Go LookUp HDCL1
GMM_DEFINE_MOCS( 0 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 1 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 2 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 3 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 4 , 0 , 0 , 0 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 5 , 0 , 0 , 3 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 6 , 1 , 1 , 3 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 7 , 1 , 3 , 3 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 8 , 1 , 7 , 3 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 48 , 0 , 0 , 3 , 0 , 0 , 1 )
GMM_DEFINE_MOCS( 49 , 0 , 0 , 1 , 0 , 0 , 1 )
GMM_DEFINE_MOCS( 60 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 61 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 62 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 63 , 0 , 0 , 1 , 0 , 0 , 0 )
CurrentMaxMocsIndex = 8;
CurrentMaxL1HdcMocsIndex = 49;
CurrentMaxSpecialMocsIndex = 63;
}
else if (GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_XE_HP_SDV)
{
//Default MOCS Table
for(int index = 0; index < GMM_MAX_NUMBER_MOCS_INDEXES; index++)
{ // Index ESC SCC L3CC Go LookUp HDCL1
GMM_DEFINE_MOCS( index , 0 , 0 , 3 , 0 , 1 , 0 )
}
// Fixed MOCS Table
// Index ESC SCC L3CC Go LookUp HDCL1
GMM_DEFINE_MOCS( 1 , 0 , 0 , 1 , 0 , 1 , 0 )
GMM_DEFINE_MOCS( 2 , 0 , 0 , 1 , 1 , 1 , 0 )
GMM_DEFINE_MOCS( 3 , 0 , 0 , 1 , 1 , 0 , 0 )
GMM_DEFINE_MOCS( 4 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 5 , 0 , 0 , 3 , 0 , 1 , 0 )
GMM_DEFINE_MOCS( 48 , 0 , 0 , 3 , 0 , 1 , 1 )
GMM_DEFINE_MOCS( 49 , 0 , 0 , 1 , 0 , 1 , 1 )
GMM_DEFINE_MOCS( 60 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 61 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 62 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 63 , 0 , 0 , 1 , 0 , 0 , 0 )
CurrentMaxMocsIndex = 5;
CurrentMaxL1HdcMocsIndex = 49;
CurrentMaxSpecialMocsIndex = 63;
}
else if ((GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_DG2))
{
//Default MOCS Table
for(int index = 0; index < GMM_MAX_NUMBER_MOCS_INDEXES; index++)
{ // Index ESC SCC L3CC Go LookUp HDCL1
GMM_DEFINE_MOCS( index , 0 , 0 , 3 , 0 , 1 , 0 )
}
// Fixed MOCS Table
// Index ESC SCC L3CC Go LookUp HDCL1
GMM_DEFINE_MOCS( 0 , 0 , 0 , 1 , 0 , 1 , 0 )
GMM_DEFINE_MOCS( 1 , 0 , 0 , 1 , 1 , 1 , 0 )
GMM_DEFINE_MOCS( 2 , 0 , 0 , 1 , 1 , 0 , 0 )
GMM_DEFINE_MOCS( 3 , 0 , 0 , 3 , 0 , 1 , 0 )
CurrentMaxMocsIndex = 3;
}
else if (GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_PVC)
{
//Default MOCS Table
for(int index = 0; index < GMM_MAX_NUMBER_MOCS_INDEXES; index++)
{ // Index ESC SCC L3CC Go LookUp HDCL1
GMM_DEFINE_MOCS( index , 0 , 0 , 3 , 0 , 0 , 0 )
}
// Fixed MOCS Table
// Index ESC SCC L3CC Go LookUp HDCL1
GMM_DEFINE_MOCS( 1 , 0 , 0 , 1 , 0 , 0 , 0 )
GMM_DEFINE_MOCS( 2 , 0 , 0 , 3 , 0 , 0 , 0 )
CurrentMaxMocsIndex = 2;
}
// clang-format on
#undef GMM_DEFINE_MOCS
}

View File

@ -0,0 +1,304 @@
/*==============================================================================
Copyright(c) 2020 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmCachePolicyConditionals.h"
#define EDRAM (SKU(FtrEDram))
#define FBLLC (SKU(FtrFrameBufferLLC))
#define L1 (!WA(Wa_1606955757))
//Macros for segment-preference
#define NoP 0x0
#define SYS 0x1
#define LOC 0x2
#define LoP 0x3
#define SyP 0x4
// Cache Policy Definition
// L3_SCC = L3 skip caching control (disabled if L3_SCC = 0)
// HDCL1 = HDC L1 cache control (1 = cached in HDC L1, 0 = not cached in HDC L1)
// Faster PushWrite(Gen10+) used iff !WT, eLLC-only cacheable - Globally visible surface (eg display surface) should be marked WT
// GO = Global observable point for L3-uncached (0=Default is L3, 1= Memory)// GO = Global observable point for L3-uncached (0=Default is L3, 1= Memory)
// UcLookup = Snoop L3 for uncached (0=Default is no-snoop, 1 =Snoop)
// L1CC: L1 cache control (0: WBP write bypass mode, 1: UC uncached, 2: WB Write back, 3:WT write-through, 4: WS Write-Streaming) : Valid only for DG2
//***********************************************************************************************************************************************************/
// USAGE TYPE , L3 , L3_SCC, HDCL1, GO, UcLookup, L1CC)
/************************************************************************************************************************************************************/
// KMD Usages
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BATCH_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMP_FRAME_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SWITCH_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CURSOR , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAY_STATIC_IMG_FOR_SMOOTH_ROTATION_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DUMMY_PAGE , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GDI_SURFACE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GENERIC_KMD_RESOURCE , 0 , 0 , 0, 0, 1, 1);
// GMM_RESOURCE_USAGE_GFX_RING is only used if WaEnableRingHostMapping is enabled.
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GFX_RING , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GTT_TRANSFER_REGION , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HW_CONTEXT , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATE_MANAGER_KERNEL_STATE , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_STAGING_SURFACE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBM_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_NNDI_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OVERLAY_MBM , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRIMARY_SURFACE , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SCREEN_PROTECTION_INTERMEDIATE_SURFACE , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADOW_SURFACE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SM_SCRATCH_STATE , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATUS_PAGE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TIMER_PERF_QUEUE , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNKNOWN , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNMAP_PAGING_RESERVED_GTT_DMA_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VSC_BATCH_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WA_BATCH_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_OCA_BUFFER , 0 , 0 , 0, 0, 1, 1);
//
// 3D Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UMD_BATCH_BUFFER , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BINDING_TABLE_POOL , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CCS , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONSTANT_BUFFER_POOL , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEPTH_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAYABLE_RENDER_TARGET , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GATHER_POOL , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_SURFACE_STATE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_DYNAMIC_STATE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE_UC , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT_L1_CACHED , 1 , 0 , L1, 0, 1, 2);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INDIRECT_OBJECT , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INSTRUCTION , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HIZ , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER_L3_COHERENT_UC , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER_L3_CACHED , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MCS , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PUSH_CONSTANT_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PULL_CONSTANT_BUFFER , 1 , 0 , 1, 0, 1, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_QUERY , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE , 1 , 0 , 1, 0, 1, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STAGING , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STENCIL_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAM_OUTPUT_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_POOL , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE_LLC_BYPASS , 1 , 0 , 1, 0, 1, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MOCS_62 , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_L3_EVICTION , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_L3_EVICTION_SPECIAL , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROCEDURAL_TEXTURE , 1 , 0 , 0, 0, 1, 1);
// Tiled Resource
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_DEPTH_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_HIZ , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_MCS , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_CCS , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 0 , 1, 0, 1, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_SHADER_RESOURCE , 1 , 0 , 1, 0, 1, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_UAV , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UAV , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER_L3_COHERENT_UC , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER_L3_CACHED , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OGL_WSTN_VERTEX_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POSH_VERTEX_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 0 , 1, 0, 1, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WDDM_HISTORY_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SAVE_RESTORE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PTBR_PAGE_POOL , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PTBR_BATCH_BUFFER , 1 , 0 , 0, 0, 1, 1);
//
// CM USAGES
//
// USAGE TYPE , L3 , L3_SCC, HDCL1, GO, UcLookup, L1CC)
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_SurfaceState, 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_L1_Enabled_SurfaceState, 1 , 0 , 1, 0, 1, 2);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_StateHeap, 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_L3_SurfaceState, 0 , 0 , 1, 0, 1, 1);
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_CACHE_SurfaceState, 0 , 0 , 0, 1, 0, 1);
//
// MP USAGES
//
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_BEGIN, 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_DEFAULT, 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_DEFAULT_FF, 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_DEFAULT_RCS, 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_SurfaceState, 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_SurfaceState_FF, 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_SurfaceState_RCS, 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_END, 0 , 0 , 0, 1, 0, 1);
// MHW - SFC
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface, 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_AvsLineBufferSurface, 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_IefLineBufferSurface, 0 , 0 , 0, 1, 0, 1);
//Media GMM Resource USAGES
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POST_DEBLOCKING_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_ENCODE , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_DECODE , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAMOUT_DATA_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INTRA_ROWSTORE_SCRATCH_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_SCRATCH_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_REFERENCE_PICTURE_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_STATUS_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_MV_OBJECT_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFD_INDIRECT_IT_COEF_OBJECT_DECODE , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFC_INDIRECT_PAKBASE_OBJECT_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BSDMPC_ROWSTORE_SCRATCH_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MPR_ROWSTORE_SCRATCH_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BITPLANE_READ_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_AACSBIT_VECTOR_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_CURR_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_REF_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_FF , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_DST , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PAK_OBJECT_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_ROW_STORE_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_STREAMIN_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MV_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_STATUS_ERROR_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_LCU_ILDB_STREAMOUT_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_SEGMENT_ID_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_HVD_ROWSTORE_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_ILDB_STREAM_OUT_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SSE_SRC_PIXEL_ROW_STORE_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SLICE_STATE_STREAM_OUT_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CABAC_SYNTAX_STREAM_OUT_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRED_COL_STORE_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_UNCACHED , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_ONLY , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_ONLY , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ELLC_LLC_L3 , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CCS_MEDIA_WRITABLE , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_HISTORY_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SOFTWARE_SCOREBOARD_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_MV_DATA_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DISTORTION_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_4XME_DISTORTION_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_INTRA_DISTORTION_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MB_STATS_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PAK_STATS_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PIC_STATE_READ_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PIC_STATE_WRITE_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_COMBINED_ENC_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_CONSTANT_DATA_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_INTERMEDIATE_CU_RECORD_SURFACE_ENCODE , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SCRATCH_ENCODE , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_LCU_LEVEL_DATA_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_HISTORY_INPUT_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_HISTORY_OUTPUT_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_DEBUG_ENCODE , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CONSTANT_TABLE_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CU_RECORD_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_MV_TEMPORAL_BUFFER_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_CU_PACKET_FOR_PAK_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_BCOMBINED1_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ENC_BCOMBINED2_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_FRAME_STATS_STREAMOUT_DATA_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_TILE_LINE_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_TILE_COLUMN_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_TILE_LINE_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_TILE_COLUMN_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_TILE_LINE_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_TILE_COLUMN_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_COUNTER_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HUC_VIRTUAL_ADDR_REGION_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SIZE_STREAMOUT_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMPRESSED_HEADER_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROBABILITY_DELTA_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_RECORD_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_SIZE_STAS_BUFFER_CODEC , 0 , 0 , 0, 1, 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MAD_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_PAK_IMAGESTATE_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_BRC_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MB_BRC_CONST_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_MB_QP_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ROI_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBDISABLE_SKIPMAP_CODEC , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_SLICE_MAP_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_WP_DOWNSAMPLED_ENCODE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_VDENC_IMAGESTATE_ENCODE , 0 , 0 , 0, 1, 0, 1);
/**********************************************************************************/
//
// OCL Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CONST , 1 , 0 , 1, 0, 1, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CSR_UC , 0 , 0 , 0, 1, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED , 0 , 0 , 0, 1, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_IMAGE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST_HDC , 1 , 0 , 1, 0, 1, 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SCRATCH , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRIVATE_MEM , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRINTF_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_STATE_HEAP_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER_CACHELINE_MISALIGNED , 0 , 0 , 0, 1, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_ISH_HEAP_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TAG_MEMORY_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TEXTURE_BUFFER , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SELF_SNOOP_BUFFER , 1 , 0 , 0, 0, 1, 1);
/**********************************************************************************/
// Cross Adapter
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE , 1 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_NULL_CONTEXT_BB , 0 , 0 , 0, 0, 1, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMMAND_STREAMER , 0 , 0 , 0, 1, 1, 1);
/**********************************************************************************/
// Uncacheable copies
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_SOURCE , 0 , 0 , 0 , 1 , 0, 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_DEST , 0 , 0 , 0 , 1 , 0, 1);
#include "GmmCachePolicyUndefineConditionals.h"

View File

@ -0,0 +1,511 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmCachePolicy.h"
//=============================================================================
//
// Function: __GmmGen8InitCachePolicy
//
// Desc: This function initializes the cache policy
//
// Parameters: pCachePolicy -> Ptr to array to be populated with the
// mapping of usages -> cache settings.
//
// Return: GMM_STATUS
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::GmmGen8CachePolicy::InitCachePolicy()
{
__GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
#define DEFINE_CACHE_ELEMENT(usage, llc, ellc, l3, wt, age) DEFINE_CP_ELEMENT(usage, llc, ellc, l3, wt, age, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#include "GmmGen8CachePolicy.h"
{
// Gen8 Memory Object Definitions
#define MO_ELLC 0x0
#define MO_LLC 0x1
#define MO_LLC_ELLC 0x2
#define MO_L3_LLC_ELLC 0x3
#define MO_USE_PTE 0x0
#define MO_UC 0x1
#define MO_WT 0x2
#define MO_WB 0x3
// Define index of cache element
uint32_t Usage = 0;
// Process Cache Policy and fill in look up table
for(; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
bool CachePolicyError = false;
uint64_t PTEValue = 0;
if(pCachePolicy[Usage].LLC && pCachePolicy[Usage].ELLC && pCachePolicy[Usage].L3)
pCachePolicy[Usage].MemoryObjectOverride.Gen8.TargetCache = MO_L3_LLC_ELLC;
else if(pCachePolicy[Usage].LLC && pCachePolicy[Usage].ELLC)
pCachePolicy[Usage].MemoryObjectOverride.Gen8.TargetCache = MO_LLC_ELLC;
else if(pCachePolicy[Usage].ELLC)
pCachePolicy[Usage].MemoryObjectOverride.Gen8.TargetCache = MO_ELLC;
else if(pCachePolicy[Usage].LLC)
pCachePolicy[Usage].MemoryObjectOverride.Gen8.TargetCache = MO_LLC;
pCachePolicy[Usage].MemoryObjectOverride.Gen8.Age = pCachePolicy[Usage].AGE;
if(pCachePolicy[Usage].WT)
pCachePolicy[Usage].MemoryObjectOverride.Gen8.CacheControl = MO_WT;
// L3 is not included because WT vs UC vs WB only effects uncore
else if(!(pCachePolicy[Usage].LLC || pCachePolicy[Usage].ELLC))
pCachePolicy[Usage].MemoryObjectOverride.Gen8.CacheControl = MO_UC;
else
pCachePolicy[Usage].MemoryObjectOverride.Gen8.CacheControl = MO_WB;
if(!GetUsagePTEValue(pCachePolicy[Usage], Usage, &PTEValue))
{
CachePolicyError = true;
}
// On error, the PTE value is set to a UC PAT entry
pCachePolicy[Usage].PTE.DwordValue = PTEValue & 0xFFFFFFFF;
pCachePolicy[Usage].PTE.HighDwordValue = 0;
pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
if(CachePolicyError)
{
GMM_ASSERTDPF("Cache Policy Init Error: Invalid Cache Programming - Element %d", Usage);
}
}
}
return GMM_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns true if usage PTE entries are set for caching, false otherwise.
///
/// @param[in] Usage: type of usage
///
/// @return true if the usage PTE entry is set for cached, false otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmGen8CachePolicy::CachePolicyIsUsagePTECached(GMM_RESOURCE_USAGE_TYPE Usage)
{
GMM_UNREFERENCED_PARAMETER(Usage);
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Initializes the Gfx PAT tables for AdvCtx and Gfx MMIO/Private PAT
/// PAT0 = WB_COHERENT or UC depending on WaGttPat0WB
/// PAT1 = UC or WB_COHERENT depending on WaGttPat0WB
/// PAT2 = WB_MOCSLESS, with TC = eLLC+LLC
/// PAT3 = WB
/// PAT4 = WT
/// PAT5 = WC
/// PAT6 = WC
/// PAT7 = WC
/// HLD says to set to PAT0/1 to WC, but since we don't have a WC in GPU,
/// WC option is same as UC. Hence setting PAT0 or PAT1 to UC.
/// Unused PAT's (5,6,7) are set to WC.
///
/// @return GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmGen8CachePolicy::SetupPAT()
{
GMM_STATUS Status = GMM_SUCCESS;
#if(defined(__GMM_KMD__))
uint32_t i = 0;
GMM_GFX_MEMORY_TYPE GfxMemType = GMM_GFX_UC_WITH_FENCE;
// No optional selection on Age or Target Cache because for an SVM-OS Age and
// Target Cache would not work [for an SVM-OS the Page Table is shared with IA
// and we don't have control of the PAT Idx]. If there is a strong ask from D3D
// or the performance analysis team, Age could be added.
// Add Class of Service when required.
GMM_GFX_TARGET_CACHE GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
uint8_t Age = 1;
uint8_t ServiceClass = 0;
int32_t * pPrivatePATTableMemoryType = NULL;
pPrivatePATTableMemoryType = pGmmLibContext->GetPrivatePATTableMemoryType();
__GMM_ASSERT(pGmmLibContext->GetSkuTable().FtrIA32eGfxPTEs);
for(i = 0; i < GMM_NUM_GFX_PAT_TYPES; i++)
{
pPrivatePATTableMemoryType[i] = -1;
}
// Set values for GmmGlobalInfo PrivatePATTable
for(i = 0; i < GMM_NUM_PAT_ENTRIES; i++)
{
GMM_PRIVATE_PAT PAT = {0};
if(pGmmLibContext->GetWaTable().WaNoMocsEllcOnly)
{
GfxTargetCache = GMM_GFX_TC_ELLC_ONLY;
}
else
{
GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
}
switch(i)
{
case PAT0:
if(pGmmLibContext->GetWaTable().WaGttPat0)
{
if(pGmmLibContext->GetWaTable().WaGttPat0WB)
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
}
else
{
GfxMemType = GMM_GFX_UC_WITH_FENCE;
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT0;
}
}
else // if GTT is not tied to PAT0 then WaGttPat0WB is NA
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
}
break;
case PAT1:
if(pGmmLibContext->GetWaTable().WaGttPat0 && !pGmmLibContext->GetWaTable().WaGttPat0WB)
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT1;
}
else
{
GfxMemType = GMM_GFX_UC_WITH_FENCE;
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT1;
}
break;
case PAT2:
// This PAT idx shall be used for MOCS'Less resources like Page Tables
// Page Tables have TC hardcoded to eLLC+LLC in Adv Ctxt. Hence making this to have same in Leg Ctxt.
// For BDW-H, due to Perf issue, TC has to be eLLC only for Page Tables when eDRAM is present.
GfxMemType = GMM_GFX_WB;
if(pGmmLibContext->GetWaTable().WaNoMocsEllcOnly)
{
GfxTargetCache = GMM_GFX_TC_ELLC_ONLY;
}
else
{
GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_MOCSLESS] = PAT2;
break;
case PAT3:
GfxMemType = GMM_GFX_WB;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB] = PAT3;
break;
case PAT4:
GfxMemType = GMM_GFX_WT;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WT] = PAT4;
break;
case PAT5:
case PAT6:
case PAT7:
GfxMemType = GMM_GFX_WC;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WC] = PAT5;
break;
default:
__GMM_ASSERT(0);
Status = GMM_ERROR;
}
PAT.PreGen10.MemoryType = GfxMemType;
PAT.PreGen10.TargetCache = GfxTargetCache;
PAT.PreGen10.Age = Age;
SetPrivatePATEntry(i, PAT);
}
#else
Status = GMM_ERROR;
#endif
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Initializes WA's needed for setting up the Private PATs
/// WaNoMocsEllcOnly, WaGttPat0, WaGttPat0GttWbOverOsIommuEllcOnly, WaGttPat0WB
///
/// @return GMM_STATUS
///
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmGen8CachePolicy::SetPATInitWA()
{
GMM_STATUS Status = GMM_SUCCESS;
WA_TABLE * pWaTable = &const_cast<WA_TABLE &>(pGmmLibContext->GetWaTable());
#if(defined(__GMM_KMD__))
pWaTable->WaGttPat0 = 1;
pWaTable->WaGttPat0WB = 1;
pWaTable->WaGttPat0GttWbOverOsIommuEllcOnly = 1;
// Platforms which support OS-IOMMU.
if(pGmmLibContext->GetSkuTable().FtrWddm2Svm)
{
pWaTable->WaGttPat0GttWbOverOsIommuEllcOnly = 0;
pWaTable->WaGttPat0WB = 0;
}
#else
Status = GMM_ERROR;
#endif
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the PAT idx that best matches the cache policy for this usage.
///
/// @param: CachePolicy: cache policy for a usage
///
/// @return PAT Idx to use in the PTE
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmGen8CachePolicy::BestMatchingPATIdx(GMM_CACHE_POLICY_ELEMENT CachePolicy)
{
uint32_t i;
uint32_t PATIdx = 0;
GMM_GFX_MEMORY_TYPE WantedMemoryType = GMM_GFX_UC_WITH_FENCE, MemoryType;
GMM_GFX_TARGET_CACHE WantedTC = GMM_GFX_TC_ELLC_LLC;
WantedMemoryType = GetWantedMemoryType(CachePolicy);
if(CachePolicy.LLC && CachePolicy.ELLC)
{
WantedTC = GMM_GFX_TC_ELLC_LLC;
}
else if(CachePolicy.LLC)
{
WantedTC = GMM_GFX_TC_LLC_ONLY;
}
else if(CachePolicy.ELLC)
{
WantedTC = GMM_GFX_TC_ELLC_ONLY; // Note: this overrides the MOCS target cache selection.
}
for(i = 1; i < GMM_NUM_PAT_ENTRIES; i++)
{
GMM_PRIVATE_PAT PAT1 = GetPrivatePATEntry(PATIdx);
GMM_PRIVATE_PAT PAT2 = GetPrivatePATEntry(i);
if(SelectNewPATIdx(WantedMemoryType, WantedTC,
(GMM_GFX_MEMORY_TYPE)PAT1.PreGen10.MemoryType, (GMM_GFX_TARGET_CACHE)PAT1.PreGen10.TargetCache,
(GMM_GFX_MEMORY_TYPE)PAT2.PreGen10.MemoryType, (GMM_GFX_TARGET_CACHE)PAT2.PreGen10.TargetCache))
{
PATIdx = i;
}
}
MemoryType = (GMM_GFX_MEMORY_TYPE)GetPrivatePATEntry(PATIdx).PreGen10.MemoryType;
if(MemoryType != WantedMemoryType)
{
// Failed to find a matching PAT entry
return GMM_PAT_ERROR;
}
return PATIdx;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Sets the GMM Private PAT in the PrivatePATTable for the PATIdx, GMM_PRIVATE_PAT
/// Entry passed
///
/// @param[in] PATIdx
/// @param[in] GMM_PRIVATE_PAT: PAT Entry
///
/// @return Pass/ fail
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::GmmGen8CachePolicy::SetPrivatePATEntry(uint32_t PATIdx, GMM_PRIVATE_PAT Entry)
{
if(PATIdx >= GMM_NUM_PAT_ENTRIES)
{
GMM_ASSERTDPF(false, "CRITICAL ERROR: INVALID PAT IDX");
return false;
}
#if(!defined(__GMM_KMD__))
GMM_UNREFERENCED_PARAMETER(Entry);
GMM_ASSERTDPF(false, "Should only be called from KMD");
return false;
#else
pGmmLibContext->GetPrivatePATTable()[PATIdx] = Entry;
return true;
#endif
}
/////////////////////////////////////////////////////////////////////////////////////
/// Gets the GMM Private PAT from the PrivatePATTable for the PATIdx passed
///
/// @param[in] PATIdx
///
/// @return GMM_PRIVATE_PAT: Entry
/////////////////////////////////////////////////////////////////////////////////////
GMM_PRIVATE_PAT GmmLib::GmmGen8CachePolicy::GetPrivatePATEntry(uint32_t PATIdx)
{
GMM_PRIVATE_PAT NullPAT = {0};
if(PATIdx >= GMM_NUM_PAT_ENTRIES)
{
GMM_ASSERTDPF(false, "CRITICAL ERROR: INVALID PAT IDX");
return NullPAT;
}
#if(!defined(__GMM_KMD__))
return NullPAT;
#else
return pGmmLibContext->GetPrivatePATTable()[PATIdx];
#endif
}
/////////////////////////////////////////////////////////////////////////////////////
/// Return true if (MT2, TC2) is a better match for (WantedMT, WantedTC)
/// than (MT1, TC1)
///
/// @param[in] WantedMT: Wanted Memory Type
/// @param[in] WantedTC: Wanted Target Cache
/// @param[in] MT1: Memory Type for PATIdx1
/// @param[in] TC1: Target Cache for PATIdx1
/// @param[in] MT2: Memory Type for PATIdx2
/// @param[in] TC2: Target Cache for PATIdx2
///
/// @return Select the new PAT Index True/False
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::GmmGen8CachePolicy::SelectNewPATIdx(GMM_GFX_MEMORY_TYPE WantedMT, GMM_GFX_TARGET_CACHE WantedTC,
GMM_GFX_MEMORY_TYPE MT1, GMM_GFX_TARGET_CACHE TC1,
GMM_GFX_MEMORY_TYPE MT2, GMM_GFX_TARGET_CACHE TC2)
{
bool SelectPAT2 = false;
// select on Memory Type
if(MT1 != WantedMT)
{
if(MT2 == WantedMT || MT2 == GMM_GFX_UC_WITH_FENCE)
{
SelectPAT2 = true;
}
goto EXIT;
}
// select on Target Cache
if(WantedTC != TC1)
{
if(WantedMT == MT2 && WantedTC == TC2)
{
SelectPAT2 = true;
}
goto EXIT;
}
EXIT:
return SelectPAT2;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns PTE value
///
/// @param[in] CachePolicyUsage: Cache Policy for Usage
///
/// @return true: success, false: failure
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::GmmGen8CachePolicy::GetUsagePTEValue(GMM_CACHE_POLICY_ELEMENT CachePolicyUsage,
uint32_t Usage,
uint64_t * pPTEDwordValue)
{
GMM_PTE_CACHE_CONTROL_BITS PTE = {0};
bool Success = true;
uint32_t PATIdx = 0;
// Don't setup PTE values in UMD
#if __GMM_KMD__
if((PATIdx = BestMatchingPATIdx(CachePolicyUsage)) == GMM_PAT_ERROR)
{
// IAe32 PAT table does not necessarily have an entry for WT memory type
// => not a cache policy init error if WT is unavailable.
Success = CachePolicyUsage.WT ? true : false;
// degrade to UC
{
GMM_CACHE_POLICY_ELEMENT CachePolicyElement = {0};
const char *MemTypes[4] = {"UC", "WC", "WT", "WB"}; // matches GMM_GFX_MEMORY_TYPE enum values
CachePolicyElement.Initialized = 1;
GMM_DPF(GFXDBG_NORMAL,
"Cache Policy Init: Degrading PAT settings to UC (uncached) from %s for Element %d\n",
MemTypes[GetWantedMemoryType(CachePolicyUsage)], Usage);
PATIdx = BestMatchingPATIdx(CachePolicyElement);
if(PATIdx == GMM_PAT_ERROR)
{
Success = false;
}
}
}
if(PATIdx != GMM_PAT_ERROR)
{
PTE.Gen8.PAT = (PATIdx & __BIT(2)) ? 1 : 0;
PTE.Gen8.PCD = (PATIdx & __BIT(1)) ? 1 : 0;
PTE.Gen8.PWT = (PATIdx & __BIT(0)) ? 1 : 0;
}
else
{
PTE.DwordValue = 0x0;
}
#else
GMM_UNREFERENCED_PARAMETER(CachePolicyUsage);
GMM_UNREFERENCED_PARAMETER(Usage);
#endif
*pPTEDwordValue = PTE.DwordValue;
return Success;
}

View File

@ -0,0 +1,205 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmCachePolicyConditionals.h"
#define ULT (SKU(FtrULT))
#define EDRAM (_ELLC > MB(0))
// [!] On Gen8, according to bpsec TC = 11b means L3, LLC and eLLC cachable.
// In order for resources to be places in L3, LLC/ELLC/L3 should be set to 1.
// ELLC = EDRAM indicate resource needed in EDRAM but ELLC = 1 indicate resource needed in L3
// Cache Policy Definition
//********************************************************************************************************************/
// USAGE TYPE , LLC , ELLC , L3 , WT , AGE )
/*********************************************************************************************************************/
// KMD Usages
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMP_FRAME_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SWITCH_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CURSOR , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAY_STATIC_IMG_FOR_SMOOTH_ROTATION_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DUMMY_PAGE , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GDI_SURFACE , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GENERIC_KMD_RESOURCE , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GFX_RING , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GTT_TRANSFER_REGION , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HW_CONTEXT , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATE_MANAGER_KERNEL_STATE , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_STAGING_SURFACE , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBM_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_NNDI_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OVERLAY_MBM , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRIMARY_SURFACE , 1 , 1 , 1 , 1 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SCREEN_PROTECTION_INTERMEDIATE_SURFACE , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADOW_SURFACE , !ULT , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SM_SCRATCH_STATE , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATUS_PAGE , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TIMER_PERF_QUEUE , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNKNOWN , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNMAP_PAGING_RESERVED_GTT_DMA_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VSC_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WA_BATCH_BUFFER , 0 , 0 , 0 , 0 , 0 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_OCA_BUFFER , 0 , 0 , 0 , 0 , 0 );
//
// 3D Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BINDING_TABLE_POOL , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONSTANT_BUFFER_POOL , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEPTH_BUFFER , !EDRAM, EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAYABLE_RENDER_TARGET , 0 , EDRAM , 0 , EDRAM , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GATHER_POOL , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_SURFACE_STATE , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_DYNAMIC_STATE , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INDIRECT_OBJECT , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INSTRUCTION , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HIZ , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER , !EDRAM, EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MCS , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PUSH_CONSTANT_BUFFER , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PULL_CONSTANT_BUFFER , 1 , 1 , 1 , 0 , 3 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_QUERY , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STAGING , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STENCIL_BUFFER , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAM_OUTPUT_BUFFER , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_POOL , 0 , EDRAM , 0 , 0 , 1 );
// Tiled Resource
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_DEPTH_BUFFER , !EDRAM, EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_HIZ , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_MCS , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_UAV , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OGL_WSTN_VERTEX_BUFFER , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UAV , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WDDM_HISTORY_BUFFER , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SAVE_RESTORE , 0 , EDRAM , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROCEDURAL_TEXTURE , 0 , 0 , 0 , 0 , 0 );
//
// CM USAGES
//
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_SurfaceState, 1 , 1 , 1 , 0 , 1 );
//
// MP USAGES
//
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_BEGIN, 0 , 0 , 0 , 0 , 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_DEFAULT, 0 , 0 , 0 , 0 , 0);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_SurfaceState, 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_No_L3_SurfaceState, 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_No_LLC_L3_SurfaceState, 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_END, 0 , 0 , 0 , 0 , 0);
//Media GMM Resource USAGES
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POST_DEBLOCKING_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_ENCODE , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_DECODE , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAMOUT_DATA_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INTRA_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_REFERENCE_PICTURE_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_STATUS_BUFFER_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_MV_OBJECT_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFD_INDIRECT_IT_COEF_OBJECT_DECODE , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFC_INDIRECT_PAKBASE_OBJECT_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BSDMPC_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MPR_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BITPLANE_READ_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_AACSBIT_VECTOR_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC , 0 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_CURR_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_REF_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_DST , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE , 1 , 1 , 1 , 0 , 1);
#if defined(__linux__) && !defined(ANDROID)
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PAK_OBJECT_ENCODE , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE , 1 , 1 , 0 , 0 , 1);
#else
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PAK_OBJECT_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE , 1 , 1 , 1 , 0 , 1);
#endif
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP8_BLOCK_MODE_COST_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP8_MB_MODE_COST_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP8_MBENC_OUTPUT_ENCODE , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP8_HISTOGRAM_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP8_L3_LLC_ENCODE , 1 , 1 , 1 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_CODEC , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_CODEC , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MV_CODEC , 1 , 1 , 0 , 0 , 1);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MB_QP_CODEC , 1 , 1 , 1 , 0 , 1);
/**********************************************************************************/
//OCL Usages
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER , 1 , 1 , 1 , 0 , 1 );
// This case is used for cases where we have kernels compiled for BTI 253 (non-cohrent) and they are cacheline mis-aligned
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED , 1 , 1 , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_IMAGE , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SCRATCH , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRIVATE_MEM , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRINTF_BUFFER , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_STATE_HEAP_BUFFER , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER , 1 , 1 , 1 , 0 , 1 );
// This case is used for cases where we have kernels compiled for BTI 253 (non-cohrent) and they are cacheline mis-aligned
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER_CACHELINE_MISALIGNED , 1 , 1 , 0 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_ISH_HEAP_BUFFER , 1 , 1 , 1 , 0 , 1 );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TAG_MEMORY_BUFFER , 1 , 1 , 1 , 0 , 1 );
// Sampler overfetch issue is fixed on BDW
/*Project: BDW:B0+
For SURFTYPE_BUFFER, SURFTYPE_1D, and SURFTYPE_2D non-array, non-MSAA, non-mip-mapped surfaces in linear memory,
the only padding requirement is to the next aligned 64-byte boundary beyond the end of the surface.
The rest of the padding requirements documented above do not apply to these surfaces.*/
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TEXTURE_BUFFER , 1 , 1 , 1 , 0 , 1 );
// Image from buffer when the image and buffer are on the kernel arguments list
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_IMAGE_FROM_BUFFER , 1 , 1 , 0 , 0 , 1 );
/**********************************************************************************/
// Cross Adapter
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE , 0 , 0 , 0 , 0 , 0);
/**********************************************************************************/
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CAMERA_CAPTURE , CAM$ , 0 , 0 , 0 , CAM$ );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_SOURCE , 0 , 0 , 0 , 0 , 0);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_DEST , 0 , 0 , 0 , 0 , 0);
#include "GmmCachePolicyUndefineConditionals.h"

View File

@ -0,0 +1,392 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmCachePolicy.h"
//=============================================================================
//
// Function: __GmmGen9InitCachePolicy
//
// Desc: This function initializes the cache policy
//
// Parameters: pCachePolicy -> Ptr to array to be populated with the
// mapping of usages -> cache settings.
//
// Return: GMM_STATUS
//
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::GmmGen9CachePolicy::InitCachePolicy()
{
__GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
#if defined(GMM_DYNAMIC_MOCS_TABLE)
#define DEFINE_CACHE_ELEMENT(usage, llc, ellc, l3, age, i915) DEFINE_CP_ELEMENT(usage, llc, ellc, l3, 0, age, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#else
// i915 only supports three GEN9 MOCS entires:
// MOCS[0]...LLC=0, ELLC=0, L3=0, AGE=0
// MOCS[1]...<N/A for GmmLib Purposes>
// MOCS[2]...LLC=1, ELLC=1, L3=1, AGE=3
#define DEFINE_CACHE_ELEMENT(usage, llc, ellc, l3, age, i915) \
do \
{ \
if((i915) == 0) \
{ \
DEFINE_CP_ELEMENT(usage, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\
} \
else if((i915) == 2) \
{ \
DEFINE_CP_ELEMENT(usage, 1, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\
} \
else \
{ \
GMM_ASSERTDPF(0, "Invalid i915 MOCS specified"); \
} \
} while(0) ////////////////////////////////////////////////////////////////
#endif
#include "GmmGen9CachePolicy.h"
#define TC_LLC (1)
#define TC_ELLC (0)
#define TC_LLC_ELLC (2)
#define LeCC_UNCACHEABLE (0x1)
#define LeCC_WB_CACHEABLE (0x3)
#define L3_UNCACHEABLE (0x1)
#define L3_WB_CACHEABLE (0x3)
#define DISABLE_SKIP_CACHING_CONTROL (0x0)
#define ENABLE_SKIP_CACHING_CONTROL (0x1)
{
uint32_t CurrentMaxIndex = 0;
GMM_CACHE_POLICY_TBL_ELEMENT *pCachePolicyTblElement = pGmmLibContext->GetCachePolicyTlbElement();
bool LLC = (pGmmLibContext->GetGtSysInfo()->LLCCacheSizeInKb > 0); // aka "Core -vs- Atom".
#if defined(_WIN32)
{
pCachePolicyTblElement[0].L3.Cacheability = L3_UNCACHEABLE;
pCachePolicyTblElement[0].LeCC.Cacheability = LeCC_UNCACHEABLE;
pCachePolicyTblElement[0].LeCC.TargetCache = LLC ? TC_LLC_ELLC : TC_ELLC; // No LLC for Broxton, GLK - keep clear configuration for LLC
}
#else
{
#define I915_GEN9_MOCS_ENTRIES 3
GMM_CACHE_POLICY_TBL_ELEMENT *pEntry = pCachePolicyTblElement;
C_ASSERT(I915_GEN9_MOCS_ENTRIES <= GMM_GEN9_MAX_NUMBER_MOCS_INDEXES);
// I915_MOCS_UNCACHED(0)...
pEntry[0].L3.Cacheability = L3_UNCACHEABLE;
pEntry[0].LeCC.Cacheability = LeCC_UNCACHEABLE;
pEntry[0].LeCC.TargetCache = TC_LLC_ELLC;
// I915_MOCS_PTE(1)...
pEntry[1] = pEntry[0]; // Unused by GmmLib clients, so set to UC.
CurrentMaxIndex++;
// I915_MOCS_CACHED(2)...
pEntry[2].L3.Cacheability = L3_WB_CACHEABLE;
pEntry[2].LeCC.Cacheability = LLC ? LeCC_WB_CACHEABLE : LeCC_UNCACHEABLE;
pEntry[2].LeCC.TargetCache = TC_LLC_ELLC;
pEntry[2].LeCC.LRUM = 3;
CurrentMaxIndex++;
}
#endif
// Process the cache policy and fill in the look up table
for(uint32_t Usage = 0; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
bool CachePolicyError = false;
uint64_t PTEValue = 0;
int32_t CPTblIdx = -1;
uint32_t j = 0;
GMM_CACHE_POLICY_TBL_ELEMENT UsageEle = {0};
UsageEle.LeCC.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned LeCC.DwordValue.
UsageEle.LeCC.SCF = pCachePolicy[Usage].SCF;
UsageEle.LeCC.PFM = 0; // TODO: decide what the page faulting mode should be
UsageEle.LeCC.SCC = 0;
UsageEle.LeCC.ESC = 0;
if(pCachePolicy[Usage].LeCC_SCC)
{
UsageEle.LeCC.SCC = pCachePolicy[Usage].LeCC_SCC;
UsageEle.LeCC.ESC = ENABLE_SKIP_CACHING_CONTROL;
}
UsageEle.LeCC.AOM = pCachePolicy[Usage].AOM;
UsageEle.LeCC.LRUM = pCachePolicy[Usage].AGE;
// default to LLC/ELLC target cache.
UsageEle.LeCC.TargetCache = TC_LLC_ELLC;
UsageEle.LeCC.Cacheability = LeCC_WB_CACHEABLE;
if(pGmmLibContext->GetPlatformInfo().Platform.eProductFamily == IGFX_BROXTON ||
pGmmLibContext->GetPlatformInfo().Platform.eProductFamily == IGFX_GEMINILAKE)
{
UsageEle.LeCC.AOM = 0;
UsageEle.LeCC.Cacheability = LeCC_UNCACHEABLE; // To avoid side effects use 01b even though 01b(UC) 11b(WB) are equivalent option
#if defined(GMM_DYNAMIC_MOCS_TABLE)
UsageEle.LeCC.TargetCache = TC_LLC; // No LLC for Broxton, but we still set it to LLC since it is needed for IA coherency cases
UsageEle.LeCC.LRUM = 0;
#else
UsageEle.LeCC.TargetCache = TC_LLC_ELLC; // To match I915_GEN9_MOCS[0]
#endif
}
else
{
if(pCachePolicy[Usage].LLC && pCachePolicy[Usage].ELLC)
{
UsageEle.LeCC.TargetCache = TC_LLC_ELLC;
}
else if(pCachePolicy[Usage].LLC)
{
UsageEle.LeCC.TargetCache = TC_LLC;
}
else if(pCachePolicy[Usage].ELLC)
{
UsageEle.LeCC.TargetCache = TC_ELLC;
}
else
{
UsageEle.LeCC.Cacheability = LeCC_UNCACHEABLE;
}
}
UsageEle.L3.Reserved = 0; // Reserved bits zeroe'd, this is so we
// we can compare the unioned L3.UshortValue.
UsageEle.L3.ESC = DISABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = 0;
UsageEle.L3.Cacheability = pCachePolicy[Usage].L3 ? L3_WB_CACHEABLE : L3_UNCACHEABLE;
if(pCachePolicy[Usage].L3_SCC)
{
UsageEle.L3.ESC = ENABLE_SKIP_CACHING_CONTROL;
UsageEle.L3.SCC = (uint16_t)pCachePolicy[Usage].L3_SCC;
}
for(j = 0; j <= CurrentMaxIndex; j++)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pCachePolicyTblElement[j];
if(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
TblEle->L3.UshortValue == UsageEle.L3.UshortValue)
{
CPTblIdx = j;
break;
}
}
// Didn't find the caching settings in one of the already programmed lookup table entries.
// Need to add a new lookup table entry.
if(CPTblIdx == -1)
{
if(CurrentMaxIndex < GMM_GEN9_MAX_NUMBER_MOCS_INDEXES - 1)
{
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &(pCachePolicyTblElement[++CurrentMaxIndex]);
CPTblIdx = CurrentMaxIndex;
TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
TblEle->L3.UshortValue = UsageEle.L3.UshortValue;
}
else
{
// Too many unique caching combinations to program the
// MOCS lookup table.
CachePolicyError = true;
GMM_ASSERTDPF(
"Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
"(we only support GMM_GEN_MAX_NUMBER_MOCS_INDEXES = %d)",
GMM_GEN9_MAX_NUMBER_MOCS_INDEXES);
// Set cache policy index to uncached.
CPTblIdx = 0;
}
}
if(!GetUsagePTEValue(pCachePolicy[Usage], Usage, &PTEValue))
{
CachePolicyError = true;
}
pCachePolicy[Usage].PTE.DwordValue = PTEValue & 0xFFFFFFFF;
pCachePolicy[Usage].PTE.HighDwordValue = 0;
pCachePolicy[Usage].MemoryObjectOverride.Gen9.Index = CPTblIdx;
pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
if(CachePolicyError)
{
GMM_ASSERTDPF("Cache Policy Init Error: Invalid Cache Programming - Element %d", Usage);
}
}
CurrentMaxMocsIndex = CurrentMaxIndex;
CurrentMaxL1HdcMocsIndex = 0;
}
return GMM_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Initializes the Gfx PAT tables for AdvCtx and Gfx MMIO/Private PAT
/// PAT0 = WB_COHERENT or UC depending on WaGttPat0WB
/// PAT1 = UC or WB_COHERENT depending on WaGttPat0WB
/// PAT2 = WB_MOCSLESS, with TC = eLLC+LLC
/// PAT3 = WB
/// PAT4 = WT
/// PAT5 = WC
/// PAT6 = WC
/// PAT7 = WC
/// HLD says to set to PAT0/1 to WC, but since we don't have a WC in GPU,
/// WC option is same as UC. Hence setting PAT0 or PAT1 to UC.
/// Unused PAT's (5,6,7) are set to WC.
///
/// @return GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmGen9CachePolicy::SetupPAT()
{
GMM_STATUS Status = GMM_SUCCESS;
#if(defined(__GMM_KMD__))
uint32_t i = 0;
GMM_GFX_MEMORY_TYPE GfxMemType = GMM_GFX_UC_WITH_FENCE;
// No optional selection on Age or Target Cache because for an SVM-OS Age and
// Target Cache would not work [for an SVM-OS the Page Table is shared with IA
// and we don't have control of the PAT Idx]. If there is a strong ask from D3D
// or the performance analysis team, Age could be added.
// Add Class of Service when required.
GMM_GFX_TARGET_CACHE GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
uint8_t Age = 1;
uint8_t ServiceClass = 0;
int32_t * pPrivatePATTableMemoryType = NULL;
pPrivatePATTableMemoryType = pGmmLibContext->GetPrivatePATTableMemoryType();
__GMM_ASSERT(pGmmLibContext->GetSkuTable().FtrIA32eGfxPTEs);
for(i = 0; i < GMM_NUM_GFX_PAT_TYPES; i++)
{
pPrivatePATTableMemoryType[i] = -1;
}
// Set values for GmmGlobalInfo PrivatePATTable
for(i = 0; i < GMM_NUM_PAT_ENTRIES; i++)
{
GMM_PRIVATE_PAT PAT = {0};
if(pGmmLibContext->GetSkuTable().FtrMemTypeMocsDeferPAT)
{
GfxTargetCache = GMM_GFX_TC_ELLC_ONLY;
}
else
{
GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
}
switch(i)
{
case PAT0:
if(pGmmLibContext->GetWaTable().WaGttPat0)
{
if(pGmmLibContext->GetWaTable().WaGttPat0WB)
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
}
else
{
GfxMemType = GMM_GFX_UC_WITH_FENCE;
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT0;
}
}
else // if GTT is not tied to PAT0 then WaGttPat0WB is NA
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
}
break;
case PAT1:
if(pGmmLibContext->GetWaTable().WaGttPat0 && !pGmmLibContext->GetWaTable().WaGttPat0WB)
{
GfxMemType = GMM_GFX_WB;
if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
{
PAT.PreGen10.Snoop = 1;
}
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT1;
}
else
{
GfxMemType = GMM_GFX_UC_WITH_FENCE;
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT1;
}
break;
case PAT2:
// This PAT idx shall be used for MOCS'Less resources like Page Tables
// Page Tables have TC hardcoded to eLLC+LLC in Adv Ctxt. Hence making this to have same in Leg Ctxt.
// For BDW-H, due to Perf issue, TC has to be eLLC only for Page Tables when eDRAM is present.
GfxMemType = GMM_GFX_WB;
GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_MOCSLESS] = PAT2;
break;
case PAT3:
GfxMemType = GMM_GFX_WB;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB] = PAT3;
break;
case PAT4:
GfxMemType = GMM_GFX_WT;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WT] = PAT4;
break;
case PAT5:
case PAT6:
case PAT7:
GfxMemType = GMM_GFX_WC;
pPrivatePATTableMemoryType[GMM_GFX_PAT_WC] = PAT5;
break;
default:
__GMM_ASSERT(0);
Status = GMM_ERROR;
}
PAT.PreGen10.MemoryType = GfxMemType;
PAT.PreGen10.TargetCache = GfxTargetCache;
PAT.PreGen10.Age = Age;
SetPrivatePATEntry(i, PAT);
}
#else
Status = GMM_ERROR;
#endif
return Status;
}

View File

@ -0,0 +1,257 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmCachePolicyConditionals.h"
// true if edram is present
#define EDRAM (_ELLC > MB(0))
// true if edram is present but not 128 MB (GT4e)
#define GT3e (_ELLC > MB(0) && _ELLC < MB(128))
// true if edram is 128 MB
#define GT4e (_ELLC == MB(128))
#define KBL_GT3e (PRODUCT(KABYLAKE) && GT3e)
//eDRAM caching of displayables not supported on certain SKL CPUs
#define DISP_IN_EDRAM (EDRAM && !pGmmLibContext->GetWaTable().WaDisableEdramForDisplayRT)
//eDRAM-Only caching, for a usage that might be encrypted, must use ENCRYPTED_PARTIALS_EDRAM
#define ENCRYPTED_PARTIALS_EDRAM (DISP_IN_EDRAM && !pGmmLibContext->GetWaTable().WaEncryptedEdramOnlyPartials)
//eDRAM-only caching of unencrypted flip chains on SKL GT4
#define UNENCRYPTED_RT_EDRAM (DISP_IN_EDRAM && (!pGmmLibContext->GetWaTable().WaEncryptedEdramOnlyPartials || !GT3e))
// for SKL 3e we generally want EDRAM_ONLY mode (LLC=0,ELLC=1) = (!GT3e, EDRAM)
// for SKL 4e we generally want "both" mode (LLC=1,ELLC=1) = (!GT3e, EDRAM)
// i915 only supports three GEN9 MOCS entires:
// MOCS[0]...LLC=0, ELLC=0, L3=0, AGE=0
// MOCS[1]...<N/A for GmmLib Purposes>
// MOCS[2]...LLC=1, ELLC=1, L3=1, AGE=3
#define UC 0
#define WB 2
//***************************************************************************************************************/
// USAGE TYPE , LLC , ELLC , L3 , AGE , i915)
/****************************************************************************************************************/
// KMD Usages
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BATCH_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMP_FRAME_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SWITCH_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CURSOR , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAY_STATIC_IMG_FOR_SMOOTH_ROTATION_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DUMMY_PAGE , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GDI_SURFACE , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GENERIC_KMD_RESOURCE , 0 , 0 , 0 , 0 , UC );
// GMM_RESOURCE_USAGE_GFX_RING is only used if WaEnableRingHostMapping is enabled.
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GFX_RING , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GTT_TRANSFER_REGION , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HW_CONTEXT , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATE_MANAGER_KERNEL_STATE , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_STAGING_SURFACE , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MBM_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_NNDI_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OVERLAY_MBM , 0 , DISP_IN_EDRAM, 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRIMARY_SURFACE , 0 , DISP_IN_EDRAM, 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SCREEN_PROTECTION_INTERMEDIATE_SURFACE , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADOW_SURFACE , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SM_SCRATCH_STATE , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STATUS_PAGE , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TIMER_PERF_QUEUE , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNKNOWN , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UNMAP_PAGING_RESERVED_GTT_DMA_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VSC_BATCH_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WA_BATCH_BUFFER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_KMD_OCA_BUFFER , 0 , 0 , 0 , 0 , UC );
//
// 3D Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UMD_BATCH_BUFFER , 0 , 0 , 0 ,0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BINDING_TABLE_POOL , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CCS , 0 , EDRAM , 1 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONSTANT_BUFFER_POOL , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEPTH_BUFFER , !GT3e , EDRAM , 0 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DISPLAYABLE_RENDER_TARGET , 0 , ENCRYPTED_PARTIALS_EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GEN9_UNENCRYPTED_DISPLAYABLE , 0 , UNENCRYPTED_RT_EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_GATHER_POOL , 0 , EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_SURFACE_STATE , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_DYNAMIC_STATE , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_GENERAL_STATE_UC , 0 , 0 , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT , 1 , 1 , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_STATELESS_DATA_PORT_L1_CACHED , 1 , 1 , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INDIRECT_OBJECT , 1 , 1 , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HEAP_INSTRUCTION , 1 , 1 , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HIZ , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INDEX_BUFFER , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MCS , 0 , EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PUSH_CONSTANT_BUFFER , 0 , EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PULL_CONSTANT_BUFFER , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_QUERY , !GT3e , EDRAM , 0 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET , !GT3e , EDRAM , 0 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SHADER_RESOURCE , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STAGING , !GT3e , EDRAM , 0 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STENCIL_BUFFER , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAM_OUTPUT_BUFFER , 0 , EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILE_POOL , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PROCEDURAL_TEXTURE , 0 , 0 , 0 ,0 , UC );
// Tiled Resource
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_DEPTH_BUFFER , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_HIZ , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_MCS , 0 , EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_CCS , 0 , EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_RENDER_TARGET_AND_SHADER_RESOURCE , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_SHADER_RESOURCE , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_TILED_UAV , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_UAV , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VERTEX_BUFFER , !GT3e , EDRAM , 0 ,1 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OGL_WSTN_VERTEX_BUFFER , !GT3e, EDRAM , 0 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE , !GT3e , EDRAM , 1 ,3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_RENDER_TARGET_AND_SHADER_RESOURCE_PARTIALENCSURFACES , !GT3e , ENCRYPTED_PARTIALS_EDRAM, 1, 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_WDDM_HISTORY_BUFFER , 0 , EDRAM , 0 ,3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CONTEXT_SAVE_RESTORE , !GT3e , EDRAM , 1 ,3 , WB );
//
// CM USAGES
//
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_SurfaceState , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_L3_SurfaceState , 1 , 1 , 0 , 3 , WB );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_ELLC_SurfaceState , 0 , 0 , 1 , 3 , UC );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_SurfaceState , 0 , 1 , 1 , 3 , UC );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_ELLC_SurfaceState , 1 , 0 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_LLC_L3_SurfaceState , 0 , 1 , 0 , 3 , UC );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_ELLC_L3_SurfaceState , 1 , 0 , 0 , 3 , WB );
DEFINE_CACHE_ELEMENT(CM_RESOURCE_USAGE_NO_CACHE_SurfaceState , 0 , 0 , 0 , 3 , UC );
//
// MP USAGES
//
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_BEGIN, 0 , 0 , 0 , 0, UC );
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_DEFAULT, 0 , 0 , 0 , 0, UC );
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_SurfaceState, 1 , EDRAM , 1 , 1, WB);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_AGE3_SurfaceState, 1 , EDRAM , 1 , 3, WB);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_No_L3_SurfaceState, 1 , EDRAM , 0 , 1, WB);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_No_LLC_L3_SurfaceState, 0 , EDRAM , 0 , 1, UC);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_No_LLC_L3_AGE_SurfaceState, 0 , EDRAM , 0 , 0, UC);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_No_LLC_eLLC_L3_AGE_SurfaceState, 0 , 0 , 0 , 0, UC);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_PartialEnc_No_LLC_L3_AGE_SurfaceState, 0 , ENCRYPTED_PARTIALS_EDRAM, 0 , 0, UC);
DEFINE_CACHE_ELEMENT(MP_RESOURCE_USAGE_END, 0 , EDRAM , 0 , 0, UC );
// MHW - SFC
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface, 0 , EDRAM , 0 , 0, UC );
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_CurrentOutputSurface_PartialEncSurface, 0 , ENCRYPTED_PARTIALS_EDRAM, 0, 0, UC );
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_AvsLineBufferSurface, 1 , EDRAM , 1 , 1, WB );
DEFINE_CACHE_ELEMENT(MHW_RESOURCE_USAGE_Sfc_IefLineBufferSurface, 1 , EDRAM , 1 , 1, WB );
//Media GMM Resource USAGES
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PRE_DEBLOCKING_CODEC_PARTIALENCSURFACE , 0 , ENCRYPTED_PARTIALS_EDRAM, 0, 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_POST_DEBLOCKING_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_ENCODE , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_ORIGINAL_UNCOMPRESSED_PICTURE_DECODE , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_STREAMOUT_DATA_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_INTRA_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DEBLOCKINGFILTER_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_REFERENCE_PICTURE_CODEC , 1 , EDRAM , 0 , 1, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MACROBLOCK_STATUS_BUFFER_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_BITSTREAM_OBJECT_DECODE , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFX_INDIRECT_MV_OBJECT_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFD_INDIRECT_IT_COEF_OBJECT_DECODE , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MFC_INDIRECT_PAKBASE_OBJECT_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BSDMPC_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_MPR_ROWSTORE_SCRATCH_BUFFER_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_BITPLANE_READ_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_AACSBIT_VECTOR_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_CURR_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_REF_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE_DST , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_PAK_OBJECT_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_FLATNESS_CHECK_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MBENC_CURBE_ENCODE , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_ROW_STORE_BUFFER_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VDENC_STREAMIN_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_SURFACE_MB_QP_CODEC , 1 , EDRAM , 1 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MD_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_SAO_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_MV_CODEC , 1 , EDRAM , 0 , 3, WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_STATUS_ERROR_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_HCP_LCU_ILDB_STREAMOUT_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_PROBABILITY_BUFFER_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_SEGMENT_ID_BUFFER_CODEC , 0 , EDRAM , 0 , 3, UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_VP9_HVD_ROWSTORE_BUFFER_CODEC , 0 , EDRAM , 0 , 3, UC );
/**********************************************************************************/
//
// OCL Usages
//
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CSR_UC , 0 , 0 , 0 , 3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_BUFFER_CACHELINE_MISALIGNED , 1 , 1 , 0 , 3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_IMAGE , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_INLINE_CONST , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SCRATCH , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRIVATE_MEM , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_PRINTF_BUFFER , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_STATE_HEAP_BUFFER , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_SYSTEM_MEMORY_BUFFER_CACHELINE_MISALIGNED , 1 , 1 , 0 , 3 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_ISH_HEAP_BUFFER , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TAG_MEMORY_BUFFER , 1 , 1 , 1 , 3 , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_OCL_TEXTURE_BUFFER , 1 , 1 , 1 , 3 , WB );
// Image from buffer when the image and buffer are on the kernel arguments list
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_OCL_IMAGE_FROM_BUFFER , 1 , 1 , 0 , 3 , WB );
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_OCL_BUFFER_NO_LLC_CACHING , 0 , 1 , 1 , 3 , UC );
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_OCL_IMAGE_NO_LLC_CACHING , 0 , 1 , 1 , 3 , UC );
/**********************************************************************************/
// Cross Adapter
DEFINE_CACHE_ELEMENT( GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE , 0 , 0 , 0 , 0, UC );
/**********************************************************************************/
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_CAMERA_CAPTURE , CAM$, 0 , 0 , CAM$ , WB );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COMMAND_STREAMER , 0 , 0 , 0 , 0 , UC );
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_SOURCE , 0 , 0 , 0 , 0 , UC);
DEFINE_CACHE_ELEMENT(GMM_RESOURCE_USAGE_COPY_DEST , 0 , 0 , 0 , 0 , UC);
#undef UC
#undef WB
#include "GmmCachePolicyUndefineConditionals.h"

View File

@ -0,0 +1,851 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmClientContext.h"
#if !__GMM_KMD__ && LHDM
#include "..\..\inc\common\gfxEscape.h"
#include "..\..\..\miniport\LHDM\inc\gmmEscape.h"
#include "Internal\Windows\GmmResourceInfoWinInt.h"
#include "../TranslationTable/GmmUmdTranslationTable.h"
#endif
extern GMM_MA_LIB_CONTEXT *pGmmMALibContext;
/////////////////////////////////////////////////////////////////////////////////////
/// Overloaded Constructor to zero initialize the GmmLib::GmmClientContext object
/// This Construtor takes pointer to GmmLibCOntext as input argumnet and initiaizes
/// ClientContext's GmmLibContext with this value
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::GmmClientContext::GmmClientContext(GMM_CLIENT ClientType, Context *pLibContext)
: ClientType(),
pUmdAdapter(),
pGmmUmdContext(),
DeviceCB(),
IsDeviceCbReceived(0)
{
this->ClientType = ClientType;
this->pGmmLibContext = pLibContext;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Destructor to free GmmLib::GmmClientContext object memory
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::GmmClientContext::~GmmClientContext()
{
pGmmLibContext = NULL;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning
/// MEMORY_OBJECT_CONTROL_STATE for a given Resource Usage Type
///
/// @param[in] GMM_RESOURCE_INFO : Pointer to ResInfo object
/// @param[in] GMM_RESOURCE_USAGE_TYPE : Resource Usage Type
/// @return MEMORY_OBJECT_CONTROL_STATE for the resource of "Usage" type.
/////////////////////////////////////////////////////////////////////////////////////
MEMORY_OBJECT_CONTROL_STATE GMM_STDCALL GmmLib::GmmClientContext::CachePolicyGetMemoryObject(GMM_RESOURCE_INFO *pResInfo, GMM_RESOURCE_USAGE_TYPE Usage)
{
return pGmmLibContext->GetCachePolicyObj()->CachePolicyGetMemoryObject(pResInfo, Usage);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning
/// GMM_PTE_CACHE_CONTROL_BITS for a given Resource Usage Type
///
/// @param[in] GMM_RESOURCE_USAGE_TYPE : Resource Usage Type
/// @return GMM_PTE_CACHE_CONTROL_BITS for the resource of "Usage" type.
/////////////////////////////////////////////////////////////////////////////////////
GMM_PTE_CACHE_CONTROL_BITS GMM_STDCALL GmmLib::GmmClientContext::CachePolicyGetPteType(GMM_RESOURCE_USAGE_TYPE Usage)
{
return pGmmLibContext->GetCachePolicyObj()->CachePolicyGetPteType(Usage);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning
/// MEMORY_OBJECT_CONTROL_STATE for a given ResInfo Object
///
/// @param[in] GMM_RESOURCE_INFO : Pointer to ResInfo object
/// @return MEMORY_OBJECT_CONTROL_STATE for the ResInfo object
/////////////////////////////////////////////////////////////////////////////////////
MEMORY_OBJECT_CONTROL_STATE GMM_STDCALL GmmLib::GmmClientContext::CachePolicyGetOriginalMemoryObject(GMM_RESOURCE_INFO *pResInfo)
{
return pGmmLibContext->GetCachePolicyObj()->CachePolicyGetOriginalMemoryObject(pResInfo);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for checking if PTE is cached for a
/// given resource usage type
///
/// @param[in] GMM_RESOURCE_USAGE_TYPE : Resource Usage Type
/// @return True if PTE cached, else false
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::CachePolicyIsUsagePTECached(GMM_RESOURCE_USAGE_TYPE Usage)
{
return pGmmLibContext->GetCachePolicyObj()->CachePolicyIsUsagePTECached(Usage);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class to return L1 Cache Control on DG2 for a
/// given resource usage type
///
/// @param[in] GMM_RESOURCE_USAGE_TYPE : Resource Usage Type
/// @return Value of L1 Cache control
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::GetSurfaceStateL1CachePolicy(GMM_RESOURCE_USAGE_TYPE Usage)
{
return pGmmLibContext->GetCachePolicyElement(Usage).L1CC;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning Max MOCS index used
/// on a platform
///
/// @return Max MOCS Index
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GMM_STDCALL GmmLib::GmmClientContext::CachePolicyGetMaxMocsIndex()
{
GMM_CACHE_POLICY * pCachePolicy = pGmmLibContext->GetCachePolicyObj();
GmmLib::GmmGen9CachePolicy *ptr = static_cast<GmmLib::GmmGen9CachePolicy *>(pCachePolicy);
return ptr->CurrentMaxMocsIndex;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning Max L1 HDC MOCS index used
/// on a platform
///
/// @return Max L1 HDC MOCS Index
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GMM_STDCALL GmmLib::GmmClientContext::CachePolicyGetMaxL1HdcMocsIndex()
{
GMM_CACHE_POLICY * pCachePolicy = pGmmLibContext->GetCachePolicyObj();
GmmLib::GmmGen9CachePolicy *ptr = static_cast<GmmLib::GmmGen9CachePolicy *>(pCachePolicy);
return ptr->CurrentMaxL1HdcMocsIndex;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns count of current Special MOCS values for MOCS Table programming at GMM boot
///
/// @param[in] none:
/// @return uint32_t max special mocs index needed to program
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GMM_STDCALL GmmLib::GmmClientContext::CachePolicyGetMaxSpecialMocsIndex(void)
{
GMM_CACHE_POLICY *pCachePolicy = pGmmLibContext->GetCachePolicyObj();
return pCachePolicy->GetMaxSpecialMocsIndex();
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning GMM_CACHE_POLICY_ELEMENT
/// Table defiend for a platform
///
/// @return Const GMM_CACHE_POLICY_ELEMENT Table
/////////////////////////////////////////////////////////////////////////////////////
GMM_CACHE_POLICY_ELEMENT *GMM_STDCALL GmmLib::GmmClientContext::GetCachePolicyUsage()
{
return (pGmmLibContext->GetCachePolicyUsage());
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for populating GMM_CACHE_SIZES
/// available on a platform
///
/// @return In/Out GMM_CACHE_SIZES Populated Caches sizes
/////////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL GmmLib::GmmClientContext::GetCacheSizes(GMM_CACHE_SIZES *pCacheSizes)
{
return GmmGetCacheSizes(pGmmLibContext, pCacheSizes);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning GMM_CACHE_POLICY_ELEMENT
/// for a given Resource Usage Type
///
/// @return GMM_CACHE_POLICY_ELEMENT
/////////////////////////////////////////////////////////////////////////////////////
GMM_CACHE_POLICY_ELEMENT GMM_STDCALL GmmLib::GmmClientContext::GetCachePolicyElement(GMM_RESOURCE_USAGE_TYPE Usage)
{
return pGmmLibContext->GetCachePolicyElement(Usage);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning GMM_CACHE_POLICY_TBL_ELEMENT
/// for a given Mocs Index
///
/// @return GMM_CACHE_POLICY_TBL_ELEMENT
/////////////////////////////////////////////////////////////////////////////////////
GMM_CACHE_POLICY_TBL_ELEMENT GMM_STDCALL GmmLib::GmmClientContext::GetCachePolicyTlbElement(uint32_t MocsIdx)
{
return pGmmLibContext->GetCachePolicyTlbElement()[MocsIdx];
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning GMM_PLATFORM_INFO data
///
/// @return GMM_PLATFORM_INFO&
/////////////////////////////////////////////////////////////////////////////////////
GMM_PLATFORM_INFO &GMM_STDCALL GmmLib::GmmClientContext::GetPlatformInfo()
{
return pGmmLibContext->GetPlatformInfo();
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for getting Alignment info
///
/// @return void
//////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL GmmLib::GmmClientContext::GetExtendedTextureAlign(uint32_t Mode, ALIGNMENT &UnitAlign)
{
ALIGNMENT AlignInfo;
pGmmLibContext->GetPlatformInfoObj()->ApplyExtendedTexAlign(Mode, AlignInfo);
UnitAlign = AlignInfo;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning SKU_FEATURE_TABLE data
///
/// @return SKU_FEATURE_TABLE&
/////////////////////////////////////////////////////////////////////////////////////
const SKU_FEATURE_TABLE &GMM_STDCALL GmmLib::GmmClientContext::GetSkuTable()
{
return pGmmLibContext->GetSkuTable();
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning whether the given Resource
/// format is Planar
///
/// @return True if the Given format is planar
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::IsPlanar(GMM_RESOURCE_FORMAT Format)
{
return GmmIsPlanar(Format);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning whether the given Resource
/// format is P0xx
///
/// @return True if the Given format is P0xx
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::IsP0xx(GMM_RESOURCE_FORMAT Format)
{
return GmmIsP0xx(Format);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning whether the given Resource
/// format is UV Packed plane
///
/// @return True if the Given format is UV packed
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::IsUVPacked(GMM_RESOURCE_FORMAT Format)
{
return GmmIsUVPacked(Format);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning whether the given Resource
/// format is Compressed
///
/// @return True if the Given format is Compressed
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::IsCompressed(GMM_RESOURCE_FORMAT Format)
{
return (Format > GMM_FORMAT_INVALID) &&
(Format < GMM_RESOURCE_FORMATS) &&
pGmmLibContext->GetPlatformInfo().FormatTable[Format].Compressed;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning whether the given Resource
/// format is YUV Packed plane
///
/// @return True if the Given format is YUV packed
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::IsYUVPacked(GMM_RESOURCE_FORMAT Format)
{
return GmmIsYUVPacked(Format);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning its GMM_SURFACESTATE_FORMAT
/// for the given equivalent GMM_RESOURCE_FORMAT type
///
/// @return GMM_SURFACESTATE_FORMAT for the given format type
/////////////////////////////////////////////////////////////////////////////////////
GMM_SURFACESTATE_FORMAT GMM_STDCALL GmmLib::GmmClientContext::GetSurfaceStateFormat(GMM_RESOURCE_FORMAT Format)
{
// ToDo: Remove the definition of GmmGetSurfaceStateFormat(Format)
return ((Format > GMM_FORMAT_INVALID) &&
(Format < GMM_RESOURCE_FORMATS)) ?
pGmmLibContext->GetPlatformInfo().FormatTable[Format].SurfaceStateFormat :
GMM_SURFACESTATE_FORMAT_INVALID;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning
/// RENDER_SURFACE_STATE::CompressionFormat
///
/// @return uint8_t
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::GetSurfaceStateCompressionFormat(GMM_RESOURCE_FORMAT Format)
{
__GMM_ASSERT((Format > GMM_FORMAT_INVALID) && (Format < GMM_RESOURCE_FORMATS));
return pGmmLibContext->GetPlatformInfo().FormatTable[Format].CompressionFormat.AuxL1eFormat;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning
/// MEDIA_SURFACE_STATE::CompressionFormat
///
/// @return uint8_t
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GMM_STDCALL GmmLib::GmmClientContext::GetMediaSurfaceStateCompressionFormat(GMM_RESOURCE_FORMAT Format)
{
__GMM_ASSERT((Format > GMM_FORMAT_INVALID) && (Format < GMM_RESOURCE_FORMATS));
return pGmmLibContext->GetPlatformInfoObj()->OverrideCompressionFormat(Format, (uint8_t)0x1);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for returning E2E compression format
///
/// @return GMM_E2ECOMP_FORMAT
/////////////////////////////////////////////////////////////////////////////////////
GMM_E2ECOMP_FORMAT GMM_STDCALL GmmLib::GmmClientContext::GetLosslessCompressionType(GMM_RESOURCE_FORMAT Format)
{
// ToDo: Remove the definition of GmmGetLosslessCompressionType(Format)
__GMM_ASSERT((Format > GMM_FORMAT_INVALID) && (Format < GMM_RESOURCE_FORMATS));
return pGmmLibContext->GetPlatformInfo().FormatTable[Format].CompressionFormat.AuxL1eFormat;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class to return InternalGpuVaMax value
/// stored in pGmmGlobalContext
///
/// @return GMM_SUCCESS
/////////////////////////////////////////////////////////////////////////////////////
uint64_t GMM_STDCALL GmmLib::GmmClientContext::GetInternalGpuVaRangeLimit()
{
return pGmmLibContext->GetInternalGpuVaRangeLimit();
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of Custiom ResourceInfo Object .
/// @see GmmLib::GmmResourceInfoCommon::Create()
///
/// @param[in] pCreateParams: Flags which specify what sort of resource to create
/// @return Pointer to GmmResourceInfo class.
/////////////////////////////////////////////////////////////////////////////////////
GMM_RESOURCE_INFO *GMM_STDCALL GmmLib::GmmClientContext::CreateCustomResInfoObject(GMM_RESCREATE_CUSTOM_PARAMS *pCreateParams)
{
GMM_RESOURCE_INFO *pRes = NULL;
GmmClientContext * pClientContextIn = NULL;
pClientContextIn = this;
if((pRes = new GMM_RESOURCE_INFO(pClientContextIn)) == NULL)
{
GMM_ASSERTDPF(0, "Allocation failed!");
goto ERROR_CASE;
}
if(pRes->CreateCustomRes(*pGmmLibContext, *pCreateParams) != GMM_SUCCESS)
{
goto ERROR_CASE;
}
return (pRes);
ERROR_CASE:
if(pRes)
{
DestroyResInfoObject(pRes);
}
return (NULL);
}
#ifndef __GMM_KMD__
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of Custiom ResourceInfo Object .
/// @see GmmLib::GmmResourceInfoCommon::CreateCustomResInfoObject_2()
///
/// @param[in] pCreateParams: Flags which specify what sort of resource to create
/// @return Pointer to GmmResourceInfo class.
/////////////////////////////////////////////////////////////////////////////////////
GMM_RESOURCE_INFO *GMM_STDCALL GmmLib::GmmClientContext::CreateCustomResInfoObject_2(GMM_RESCREATE_CUSTOM_PARAMS_2 *pCreateParams)
{
GMM_RESOURCE_INFO *pRes = NULL;
GmmClientContext * pClientContextIn = NULL;
pClientContextIn = this;
if((pRes = new GMM_RESOURCE_INFO(pClientContextIn)) == NULL)
{
GMM_ASSERTDPF(0, "Allocation failed!");
goto ERROR_CASE;
}
if(pRes->CreateCustomRes_2(*pGmmLibContext, *pCreateParams) != GMM_SUCCESS)
{
goto ERROR_CASE;
}
return (pRes);
ERROR_CASE:
if(pRes)
{
DestroyResInfoObject(pRes);
}
return (NULL);
}
#endif
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of ResourceInfo Object .
/// @see GmmLib::GmmResourceInfoCommon::Create()
///
/// @param[in] pCreateParams: Flags which specify what sort of resource to create
/// @return Pointer to GmmResourceInfo class.
/////////////////////////////////////////////////////////////////////////////////////
GMM_RESOURCE_INFO *GMM_STDCALL GmmLib::GmmClientContext::CreateResInfoObject(GMM_RESCREATE_PARAMS *pCreateParams)
{
GMM_RESOURCE_INFO *pRes = NULL;
GmmClientContext * pClientContextIn = NULL;
#if(!defined(GMM_UNIFIED_LIB))
pClientContextIn = pGmmLibContext->pGmmGlobalClientContext;
#else
pClientContextIn = this;
#endif
GMM_DPF_ENTER;
// GMM_RESOURCE_INFO...
if(pCreateParams->pPreallocatedResInfo)
{
pRes = new(pCreateParams->pPreallocatedResInfo) GmmLib::GmmResourceInfo(pClientContextIn); // Use preallocated memory as a class
pCreateParams->Flags.Info.__PreallocatedResInfo =
pRes->GetResFlags().Info.__PreallocatedResInfo = 1; // Set both in case we can die before copying over the flags.
}
else
{
if((pRes = new GMM_RESOURCE_INFO(pClientContextIn)) == NULL)
{
GMM_ASSERTDPF(0, "Allocation failed!");
goto ERROR_CASE;
}
}
if(pRes->Create(*pGmmLibContext, *pCreateParams) != GMM_SUCCESS)
{
goto ERROR_CASE;
}
GMM_DPF_EXIT;
return (pRes);
ERROR_CASE:
if(pRes)
{
DestroyResInfoObject(pRes);
}
return (NULL);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of ResourceInfo Object from
/// already created Src ResInfo object
/// @see GmmLib::GmmResourceInfoCommon::Create()
///
/// @param[in] pSrcRes: Existing ResInfoObj
/// @return Pointer to GmmResourceInfo class.
/////////////////////////////////////////////////////////////////////////////////////
GMM_RESOURCE_INFO *GMM_STDCALL GmmLib::GmmClientContext::CopyResInfoObject(GMM_RESOURCE_INFO *pSrcRes)
{
GMM_RESOURCE_INFO *pResCopy = NULL;
GmmClientContext * pClientContextIn = NULL;
#if(!defined(GMM_UNIFIED_LIB))
pClientContextIn = pGmmLibContext->pGmmGlobalClientContext;
#else
pClientContextIn = this;
#endif
__GMM_ASSERTPTR(pSrcRes, NULL);
pResCopy = new GMM_RESOURCE_INFO(pClientContextIn);
if(!pResCopy)
{
GMM_ASSERTDPF(0, "Allocation failed.");
return NULL;
}
// Set the GmmLibContext for newly created DestResInfo object
pResCopy->SetGmmLibContext(pGmmLibContext);
*pResCopy = *pSrcRes;
// Set the client type to the client for which this resinfo is created
pResCopy->SetClientType(GetClientType());
// We are allocating new class, flag must be false to avoid leak at DestroyResource
pResCopy->GetResFlags().Info.__PreallocatedResInfo = 0;
return (pResCopy);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for copy of ResourceInfo Object from
/// already created Src ResInfo object
/// @see GmmLib::GmmResourceInfoCommon::Create()
///
/// @param[in] pDst: Pointer to memory when pSrc will be copied
/// @param[in] pSrc: Pointer to GmmResourceInfo class that needs to be copied
/////////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL GmmLib::GmmClientContext::ResMemcpy(void *pDst, void *pSrc)
{
GmmClientContext *pClientContextIn = NULL;
#if(!defined(GMM_UNIFIED_LIB))
pClientContextIn = pGmmLibContext->pGmmGlobalClientContext;
#else
pClientContextIn = this;
#endif
GMM_RESOURCE_INFO *pResSrc = reinterpret_cast<GMM_RESOURCE_INFO *>(pSrc);
// Init memory correctly, in case the pointer is a raw memory pointer
GMM_RESOURCE_INFO *pResDst = new(pDst) GMM_RESOURCE_INFO(pClientContextIn);
// Set the GmmLibContext for newly created DestResInfo object
pResDst->SetGmmLibContext(pGmmLibContext);
*pResDst = *pResSrc;
// Set the client type to the client for which this resinfo is created
pResDst->SetClientType(GetClientType());
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for Destroying ResInfoObject
///
/// @param[in] pResInfo: Pointer to ResInfoObject
/// @return void.
/////////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL GmmLib::GmmClientContext::DestroyResInfoObject(GMM_RESOURCE_INFO *pResInfo)
{
__GMM_ASSERTPTR(pResInfo, VOIDRETURN);
if(pResInfo->GetResFlags().Info.__PreallocatedResInfo)
{
*pResInfo = GmmLib::GmmResourceInfo();
}
else
{
delete pResInfo;
pResInfo = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of PAgeTableMgr Object .
/// @see GmmLib::GMM_PAGETABLE_MGR::GMM_PAGETABLE_MGR
///
/// @param[in] TTFags
/// @return Pointer to GMM_PAGETABLE_MGR class.
/////////////////////////////////////////////////////////////////////////////////////
GMM_PAGETABLE_MGR* GMM_STDCALL GmmLib::GmmClientContext::CreatePageTblMgrObject(uint32_t TTFlags)
{
if (!IsDeviceCbReceived)
{
GMM_ASSERTDPF(0, "Device_callbacks not set");
return NULL;
}
return CreatePageTblMgrObject(&DeviceCB, TTFlags);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of PAgeTableMgr Object .
/// @see GmmLib::GMM_PAGETABLE_MGR::GMM_PAGETABLE_MGR
///
/// @param[in] pDevCb: Pointer to GMM_DEVICE_CALLBACKS_INT
/// @param[in] TTFags
/// @return Pointer to GMM_PAGETABLE_MGR class.
// move the code to new overloaded the API and remove this API once all clients are moved to new API.
/////////////////////////////////////////////////////////////////////////////////////
GMM_PAGETABLE_MGR* GMM_STDCALL GmmLib::GmmClientContext::CreatePageTblMgrObject(GMM_DEVICE_CALLBACKS_INT* pDevCb,
uint32_t TTFlags)
{
GMM_PAGETABLE_MGR* pPageTableMgr = NULL;
pPageTableMgr = new GMM_PAGETABLE_MGR(pDevCb, TTFlags, this);
return pPageTableMgr;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for destroy of PageTableMgr Object .
///
/// @param[in] pPageTableMgr: Pointer to GMM_PAGETABLE_MGR
/// @return void.
/////////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL GmmLib::GmmClientContext::DestroyPageTblMgrObject(GMM_PAGETABLE_MGR* pPageTableMgr)
{
if (pPageTableMgr)
{
delete pPageTableMgr;
}
}
#ifdef GMM_LIB_DLL
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of ResourceInfo Object .
/// @see GmmLib::GmmResourceInfoCommon::Create()
///
/// @param[in] pCreateParams: Flags which specify what sort of resource to create
/// @return Pointer to GmmResourceInfo class.
/////////////////////////////////////////////////////////////////////////////////////
GMM_RESOURCE_INFO *GMM_STDCALL GmmLib::GmmClientContext::CreateResInfoObject(GMM_RESCREATE_PARAMS * pCreateParams,
GmmClientAllocationCallbacks *pAllocCbs)
{
if(!pAllocCbs || !pAllocCbs->pfnAllocation)
{
return CreateResInfoObject(pCreateParams);
}
else
{
GMM_RESOURCE_INFO *pRes = NULL;
void * pConst = NULL;
// GMM_RESOURCE_INFO...
if(pCreateParams->pPreallocatedResInfo)
{
pRes = new(pCreateParams->pPreallocatedResInfo) GmmLib::GmmResourceInfo(this); // Use preallocated memory as a class
pCreateParams->Flags.Info.__PreallocatedResInfo =
pRes->GetResFlags().Info.__PreallocatedResInfo = 1; // Set both in case we can die before copying over the flags.
}
else
{
pConst = pAllocCbs->pfnAllocation(pAllocCbs->pUserData,
sizeof(GMM_RESOURCE_INFO),
alignof(GMM_RESOURCE_INFO));
if(pConst == NULL)
{
GMM_ASSERTDPF(0, "Allocation failed!");
goto ERROR_CASE;
}
else
{
pRes = new(pConst) GMM_RESOURCE_INFO(this);
}
}
if(pRes->Create(*pGmmLibContext, *pCreateParams) != GMM_SUCCESS)
{
goto ERROR_CASE;
}
return (pRes);
ERROR_CASE:
if(pRes)
{
if(pAllocCbs->pfnFree)
{
#ifdef _WIN32
pRes->~GmmResourceInfoWin();
#else
pRes->~GmmResourceInfoLin();
#endif
pAllocCbs->pfnFree(pAllocCbs->pUserData, (void *)pRes);
}
}
return (NULL);
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for Destroying ResInfoObject
///
/// @param[in] pResInfo: Pointer to ResInfoObject
/// @return void.
/////////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL GmmLib::GmmClientContext::DestroyResInfoObject(GMM_RESOURCE_INFO * pResInfo,
GmmClientAllocationCallbacks *pAllocCbs)
{
__GMM_ASSERTPTR(pResInfo, VOIDRETURN);
if(!pAllocCbs || !pAllocCbs->pfnFree)
{
return DestroyResInfoObject(pResInfo);
}
else
{
if(pResInfo->GetResFlags().Info.__PreallocatedResInfo)
{
*pResInfo = GmmLib::GmmResourceInfo();
}
else
{
#ifdef _WIN32
pResInfo->~GmmResourceInfoWin();
#else
pResInfo->~GmmResourceInfoLin();
#endif
pAllocCbs->pfnFree(pAllocCbs->pUserData, (void *)pResInfo);
pResInfo = NULL;
}
}
}
#endif
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of PAgeTableMgr Object .
/// @see GmmLib::GMM_PAGETABLE_MGR::GMM_PAGETABLE_MGR
///
/// @param[in] TTFags
/// @return Pointer to GMM_PAGETABLE_MGR class.
/////////////////////////////////////////////////////////////////////////////////////
GMM_PAGETABLE_MGR* GMM_STDCALL GmmLib::GmmClientContext::CreatePageTblMgrObject(uint32_t TTFlags,
GmmClientAllocationCallbacks* pAllocCbs)
{
if (!IsDeviceCbReceived)
{
GMM_ASSERTDPF(0, "Device_callbacks not set");
return NULL;
}
return CreatePageTblMgrObject(
&DeviceCB,
TTFlags,
pAllocCbs);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for creation of PAgeTableMgr Object .
/// @see GmmLib::GMM_PAGETABLE_MGR::GMM_PAGETABLE_MGR
///
/// @param[in] pDevCb: Pointer to GMM_DEVICE_CALLBACKS_INT
/// @param[in] TTFags
/// @return Pointer to GMM_PAGETABLE_MGR class.
/// move the code to new overloaded the API and remove this API once all clients are moved to new API.
/////////////////////////////////////////////////////////////////////////////////////
GMM_PAGETABLE_MGR* GMM_STDCALL GmmLib::GmmClientContext::CreatePageTblMgrObject(
GMM_DEVICE_CALLBACKS_INT* pDevCb,
uint32_t TTFlags,
GmmClientAllocationCallbacks* pAllocCbs)
{
if (!pAllocCbs || !pAllocCbs->pfnAllocation)
{
return CreatePageTblMgrObject(
pDevCb,
TTFlags);
}
else
{
GMM_PAGETABLE_MGR* pPageTableMgr = NULL;
return pPageTableMgr;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for destroy of PageTableMgr Object .
///
/// @param[in] pPageTableMgr: Pointer to GMM_PAGETABLE_MGR
/// @return void.
/////////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL GmmLib::GmmClientContext::DestroyPageTblMgrObject(GMM_PAGETABLE_MGR* pPageTableMgr,
GmmClientAllocationCallbacks* pAllocCbs)
{
if (!pAllocCbs || !pAllocCbs->pfnFree)
{
return DestroyPageTblMgrObject(pPageTableMgr);
}
}
////////////////////////////////////////////////////////////////////////////////////
/// Member function of ClientContext class for doing device specific operations.
/// Clients must call it before any Gfx resource (incl. svm)
/// is mapped, must happen before any use of GfxPartition, or PageTableMgr init.
/// @param[in] DeviceInfo : Pointer to info related to Device Operations.
/// @return GMM_STATUS.
//////////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmClientContext::GmmSetDeviceInfo(GMM_DEVICE_INFO* DeviceInfo)
{
GMM_STATUS Status = GMM_SUCCESS;
if (DeviceInfo == NULL || DeviceInfo->pDeviceCb == NULL)
{
return GMM_INVALIDPARAM;
}
DeviceCB = *(DeviceInfo->pDeviceCb);
IsDeviceCbReceived = 1;
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Gmm lib DLL C wrapper for creating GmmLib::GmmClientContext object
/// This C wrapper is used for Multi-Adapter scenarios to take in Adapter's BDF as
/// additional input argument to derive its correspodning GmmLibContext
///
/// @see Class GmmLib::GmmClientContext
///
/// @param[in] ClientType : describles the UMD clients such as OCL, DX, OGL, Vulkan etc
/// @param[in] sBDF: Adapter's BDF info
///
/// @return Pointer to GmmClientContext, if Context is created
/////////////////////////////////////////////////////////////////////////////////////
extern "C" GMM_CLIENT_CONTEXT *GMM_STDCALL GmmCreateClientContextForAdapter(GMM_CLIENT ClientType,
ADAPTER_BDF sBdf)
{
GMM_CLIENT_CONTEXT *pGmmClientContext = nullptr;
GMM_LIB_CONTEXT * pLibContext = pGmmMALibContext->GetAdapterLibContext(sBdf);
pGmmClientContext = new GMM_CLIENT_CONTEXT(ClientType, pLibContext);
return pGmmClientContext;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Gmm lib DLL exported C wrapper for deleting GmmLib::GmmClientContext object
/// @see Class GmmLib::GmmClientContext
///
/// @param[in] GMM_CLIENT_CONTEXT * : Pointer to ClientContext object
/// @return Void
/////////////////////////////////////////////////////////////////////////////////////
extern "C" void GMM_STDCALL GmmDeleteClientContext(GMM_CLIENT_CONTEXT *pGmmClientContext)
{
if(pGmmClientContext)
{
delete pGmmClientContext;
pGmmClientContext = NULL;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#endif
#include <iostream>
#include <stddef.h>
#ifdef GMM_LIB_DLL
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmClientContext.h"
#include "External/Common/GmmLibDll.h"
/////////////////////////////////////////////////////////////////////////////////////
// First Call to GMM Lib DLL/so to initialize singleton global context
// and create client context
/////////////////////////////////////////////////////////////////////////////////////
extern "C" GMM_LIB_API GMM_STATUS GMM_STDCALL InitializeGmm(GMM_INIT_IN_ARGS *pInArgs,
GMM_INIT_OUT_ARGS *pOutArgs)
{
GMM_STATUS Status = GMM_ERROR;
if(pInArgs && pOutArgs)
{
#if GMM_LIB_DLL_MA
ADAPTER_BDF stAdapterBDF;
#ifdef _WIN32
stAdapterBDF = pInArgs->stAdapterBDF;
#else
stAdapterBDF.Data = pInArgs->FileDescriptor;
#endif
Status = GmmCreateLibContext(pInArgs->Platform, pInArgs->pSkuTable, pInArgs->pWaTable,
pInArgs->pGtSysInfo, stAdapterBDF);
if(Status == GMM_SUCCESS)
{
pOutArgs->pGmmClientContext = GmmCreateClientContextForAdapter(pInArgs->ClientType,
stAdapterBDF);
}
#endif
}
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Destroys singleton global context and client context
///
/////////////////////////////////////////////////////////////////////////////////////
extern "C" GMM_LIB_API void GMM_STDCALL GmmAdapterDestroy(GMM_INIT_OUT_ARGS *pInArgs)
{
if(pInArgs && pInArgs->pGmmClientContext)
{
#if GMM_LIB_DLL_MA
ADAPTER_BDF stAdapterBDF = pInArgs->pGmmClientContext->GetLibContext()->sBdf;
GmmDeleteClientContext(pInArgs->pGmmClientContext);
GmmLibContextFree(stAdapterBDF);
#endif
}
}
#endif // GMM_LIB_DLL

184
Source/GmmLib/Linux.cmake Normal file
View File

@ -0,0 +1,184 @@
# Copyright(c) 2017 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files(the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and / or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#this file should contain only compiler and linker flags
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^aarch")
SET (GMMLIB_COMPILER_FLAGS_COMMON
#general warnings
#-Wall
-Winit-self
-Winvalid-pch
-Wpointer-arith
-Wno-unused
-Wno-unknown-pragmas
-Wno-comments
-Wno-narrowing
-Wno-overflow
-Wno-parentheses
-Wno-missing-braces
-Wno-sign-compare
-Werror=address
-Werror=format-security
-Werror=non-virtual-dtor
-Werror=return-type
# General optimization options
-march=${GMMLIB_MARCH}
-finline-functions
-fno-short-enums
-Wa,--noexecstack
-fno-strict-aliasing
# Common defines
-DUSE_NEON
# Other common flags
-fstack-protector
-fdata-sections
-ffunction-sections
-fmessage-length=0
-fvisibility=hidden
-fPIC
-g
)
else()
SET (GMMLIB_COMPILER_FLAGS_COMMON
#general warnings
-Wall
-Winit-self
-Winvalid-pch
-Wpointer-arith
-Wno-unused
-Wno-unknown-pragmas
-Wno-comments
-Wno-narrowing
-Wno-overflow
-Wno-parentheses
-Wno-missing-braces
-Wno-sign-compare
-Wno-enum-compare
-Werror=address
-Werror=format-security
-Werror=non-virtual-dtor
-Werror=return-type
# General optimization options
-march=${GMMLIB_MARCH}
-mpopcnt
-msse
-msse2
-msse3
-mssse3
-msse4
-msse4.1
-msse4.2
-mfpmath=sse
-finline-functions
-fno-short-enums
-Wa,--noexecstack
-fno-strict-aliasing
# Common defines
-DUSE_MMX
-DUSE_SSE
-DUSE_SSE2
-DUSE_SSE3
-DUSE_SSSE3
# Other common flags
-fstack-protector
-fdata-sections
-ffunction-sections
-fmessage-length=0
-fvisibility=hidden
-fPIC
-g
# -m32 or -m64
-m${GMMLIB_ARCH}
)
endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
#Gcc only flags
list (APPEND GMMLIB_COMPILER_FLAGS_COMMON
-funswitch-loops
-Wl,--no-undefined
-Wl,--no-as-needed
-Wl,--gc-sections
)
endif()
SET (GMMLIB_COMPILER_CXX_FLAGS_COMMON
#cpp
-Wno-reorder
-Wsign-promo
-Wnon-virtual-dtor
-Wno-invalid-offsetof
-fvisibility-inlines-hidden
-fno-use-cxa-atexit
-fno-rtti
-fexceptions
-fcheck-new
-std=c++11
-pthread
)
SET (GMMLIB_COMPILER_FLAGS_DEBUG
-O0
-DINSTR_GTUNE_EXT
)
SET (GMMLIB_COMPILER_FLAGS_RELEASE
-O2
-fno-omit-frame-pointer
#-flto
#-Wl,-flto
)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
list(APPEND GMMLIB_COMPILER_FLAGS_RELEASE
-finline-limit=100
)
endif()
#if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
# For LTO support, use special wrappers around ar and ranlib commands:
# ... and if using "nm", use gcc-nm
# SET(CMAKE_AR "gcc-ar")
# SET(CMAKE_RANLIB "gcc-ranlib")
#endif()
SET( GMMLIB_COMPILER_FLAGS_RELEASEINTERNAL ${GMMLIB_COMPILER_FLAGS_RELEASE})
#set predefined compiler flags set
add_compile_options("${GMMLIB_COMPILER_FLAGS_COMMON}")
add_compile_options("$<$<CONFIG:Debug>:${GMMLIB_COMPILER_FLAGS_DEBUG}>")
add_compile_options("$<$<CONFIG:Release>:${GMMLIB_COMPILER_FLAGS_RELEASE}>")
add_compile_options("$<$<CONFIG:ReleaseInternal>:${GMMLIB_COMPILER_FLAGS_RELEASEINTERNAL}>")
#cmake 3.3+, add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:${GMMLIB_COMPILER_CXX_FLAGS_COMMON}>")
foreach (flag ${GMMLIB_COMPILER_CXX_FLAGS_COMMON})
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
endforeach()
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^aarch")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
else()
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m${GMMLIB_ARCH}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m${GMMLIB_ARCH}")
endif()

View File

@ -0,0 +1,513 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "Internal/Common/Platform/GmmGen10Platform.h"
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates This function will initialize the necessary info based on platform.
/// - Buffer type restrictions (Eg: Z, Color, Display)
/// - X/Y tile dimensions
///
/// @param[in] Platform: Contains information about platform to initialize an object
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::PlatformInfoGen10::PlatformInfoGen10(PLATFORM &Platform, Context *pGmmLibContext)
: PlatformInfo(Platform, pGmmLibContext)
{
__GMM_ASSERTPTR(pGmmLibContext, VOIDRETURN);
// --------------------------
// Non Native Dispay Interface buffer restriction. Register Ref: DSPACNTR, DSPASTRIDE, DSPASURF
// Clamping res based on 2 Nndi buffers and GMM_NNDI_SEGMENT_SIZE reserved gfx memory
// --------------------------
Data.Nndi.Alignment = PAGE_SIZE;
Data.Nndi.PitchAlignment = GMM_BYTES(1);
Data.Nndi.RenderPitchAlignment = GMM_BYTES(1);
Data.Nndi.LockPitchAlignment = GMM_BYTES(1);
Data.Nndi.MinPitch = GMM_BYTES(640);
Data.Nndi.MaxPitch = GMM_BYTES(8192);
Data.Nndi.MinAllocationSize = PAGE_SIZE;
Data.Nndi.MinHeight = GMM_SCANLINES(200);
Data.Nndi.MinWidth = GMM_PIXELS(320);
Data.Nndi.MinDepth = 0;
Data.Nndi.MaxHeight = GMM_BYTES(1536);
Data.Nndi.MaxWidth = GMM_BYTES(2048);
Data.Nndi.MaxDepth = 1;
Data.Nndi.MaxArraySize = 1;
// --------------------------
// Depth Buffer Restriction. Inst Ref: 3DSTATE_DEPTH_BUFFER
// --------------------------
Data.Depth.Alignment = PAGE_SIZE;
Data.Depth.PitchAlignment = GMM_BYTES(64);
Data.Depth.RenderPitchAlignment = GMM_BYTES(64);
Data.Depth.LockPitchAlignment = GMM_BYTES(64);
Data.Depth.MinPitch = GMM_BYTES(64);
Data.Depth.MaxPitch = GMM_KBYTE(128); // 3DSTATE_DEPTH_BUFFER has conflicting info--but 128KB should be fine.
Data.Depth.MinAllocationSize = PAGE_SIZE;
Data.Depth.MinHeight = GMM_SCANLINES(1);
Data.Depth.MinWidth = GMM_PIXELS(1);
Data.Depth.MinDepth = 0;
Data.Depth.MaxHeight = GMM_KBYTE(16);
Data.Depth.MaxWidth = GMM_KBYTE(16);
Data.Depth.MaxDepth = GMM_KBYTE(2);
Data.Depth.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Stencil Buffer Restriction. Inst Ref: 3DSTATE_STENCIL_BUFFER
// --------------------------
Data.Stencil.Alignment = PAGE_SIZE;
Data.Stencil.PitchAlignment = GMM_BYTES(128);
Data.Stencil.RenderPitchAlignment = GMM_BYTES(128);
Data.Stencil.LockPitchAlignment = GMM_BYTES(128);
Data.Stencil.MinPitch = GMM_BYTES(128);
Data.Stencil.MaxPitch = GMM_KBYTE(128); // 3DSTATE_STENCIL_BUFFER: 2*Pitch <= 128KB (GMM client allocs 2x-width, so GMM limits to that.)
Data.Stencil.MinAllocationSize = PAGE_SIZE;
Data.Stencil.MinHeight = GMM_SCANLINES(1);
Data.Stencil.MinWidth = GMM_PIXELS(1);
Data.Stencil.MinDepth = 0;
Data.Stencil.MaxHeight = GMM_KBYTE(16);
Data.Stencil.MaxWidth = GMM_KBYTE(16);
Data.Stencil.MaxDepth = GMM_KBYTE(2);
Data.Stencil.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Hierarchical Depth Buffer Restriction. Inst Ref: 3DSTATE_HIER_DEPTH_BUFFER
// --------------------------
Data.HiZ.Alignment = PAGE_SIZE;
Data.HiZ.PitchAlignment = GMM_BYTES(128);
Data.HiZ.RenderPitchAlignment = GMM_BYTES(128);
Data.HiZ.LockPitchAlignment = GMM_BYTES(128);
Data.HiZ.MinPitch = GMM_BYTES(128);
Data.HiZ.MaxPitch = GMM_KBYTE(128);
Data.HiZ.MinAllocationSize = PAGE_SIZE;
Data.HiZ.MinHeight = GMM_SCANLINES(1);
Data.HiZ.MinWidth = GMM_PIXELS(1);
Data.HiZ.MinDepth = 0;
Data.HiZ.MaxHeight = GMM_KBYTE(16);
Data.HiZ.MaxWidth = GMM_KBYTE(16);
Data.HiZ.MaxDepth = GMM_KBYTE(2);
Data.HiZ.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Vertex Restriction. Inst Ref: 3DSTATE_VERTEX_BUFFER, 3DSTATE_INSTANCE_STEP_RATE
// Note: restrictions are expanded here for UMD flexibility.
// --------------------------
Data.Vertex.Alignment = PAGE_SIZE;
Data.Vertex.PitchAlignment = GMM_BYTES(1);
Data.Vertex.LockPitchAlignment = GMM_BYTES(1);
Data.Vertex.RenderPitchAlignment = GMM_BYTES(1);
Data.Vertex.MinPitch = GMM_BYTES(1);
Data.Vertex.MaxPitch = GMM_GBYTE(2);
Data.Vertex.MinAllocationSize = PAGE_SIZE;
Data.Vertex.MinHeight = GMM_SCANLINES(1);
Data.Vertex.MinWidth = GMM_PIXELS(1);
Data.Vertex.MinDepth = 0;
Data.Vertex.MaxHeight = GMM_MBYTE(128); //TODO(Minor): How does Media fail when we change this to 1?!
Data.Vertex.MaxWidth = GMM_GBYTE(2);
Data.Vertex.MaxDepth = GMM_KBYTE(2);
Data.Vertex.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Index Buffer Restriction. Inst Ref: 3DSTATE_INDEX_BUFFER
// --------------------------
Data.Index = Data.Vertex;
// --------------------------
// Linear Buffer Restriction. General purpose. Flexible.
// --------------------------
Data.Linear.Alignment = PAGE_SIZE;
Data.Linear.PitchAlignment = GMM_BYTES(1);
Data.Linear.LockPitchAlignment = GMM_BYTES(1);
Data.Linear.RenderPitchAlignment = GMM_BYTES(1);
Data.Linear.MinPitch = GMM_BYTES(1);
Data.Linear.MaxPitch = GMM_GBYTE(256);
Data.Linear.MinAllocationSize = PAGE_SIZE;
Data.Linear.MinHeight = GMM_SCANLINES(1);
Data.Linear.MinWidth = GMM_PIXELS(1);
Data.Linear.MinDepth = 0;
Data.Linear.MaxHeight = 1;
Data.Linear.MaxWidth = GMM_GBYTE(256);
Data.Linear.MaxDepth = 1;
Data.Linear.MaxArraySize = 1;
// --------------------------
// No Surface Restriction. General purpose. Flexible.
// --------------------------
Data.NoRestriction.Alignment = PAGE_SIZE;
Data.NoRestriction.PitchAlignment = GMM_BYTES(1);
Data.NoRestriction.LockPitchAlignment = GMM_BYTES(1);
Data.NoRestriction.RenderPitchAlignment = GMM_BYTES(1);
Data.NoRestriction.MinPitch = GMM_BYTES(1);
Data.NoRestriction.MaxPitch = GMM_TBYTE(128);
Data.NoRestriction.MinAllocationSize = PAGE_SIZE;
Data.NoRestriction.MinHeight = GMM_SCANLINES(1);
Data.NoRestriction.MinWidth = GMM_PIXELS(1);
Data.NoRestriction.MinDepth = 0;
Data.NoRestriction.MaxHeight = GMM_GBYTE(256);
Data.NoRestriction.MaxWidth = GMM_TBYTE(128);
Data.NoRestriction.MaxDepth = GMM_KBYTE(2);
Data.NoRestriction.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Constant Buffer Restriction.
// --------------------------
Data.Constant = Data.NoRestriction;
// --------------------------
// Dx9 Constant Buffer pool Restriction. Inst Ref: 3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC
// --------------------------
Data.StateDx9ConstantBuffer = Data.NoRestriction;
Data.StateDx9ConstantBuffer.Alignment = GMM_KBYTE(8);
// --------------------------
// MC Buffer Restriction
// --------------------------
Data.MotionComp = Data.NoRestriction;
Data.MotionComp.Alignment = PAGE_SIZE;
Data.MotionComp.PitchAlignment = GMM_BYTES(32);
Data.MotionComp.LockPitchAlignment = GMM_BYTES(32);
Data.MotionComp.RenderPitchAlignment = GMM_BYTES(32);
Data.MotionComp.MinPitch = GMM_BYTES(32);
// --------------------------
// Stream Buffer Restriction
// --------------------------
Data.Stream = Data.NoRestriction;
// --------------------------
// Interlace Scan Buffer Restriction
// --------------------------
Data.InterlacedScan = Data.NoRestriction;
// --------------------------
// Text API Buffer Restriction
// --------------------------
Data.TextApi = Data.NoRestriction;
// --------------------------
// RT & Texture2DSurface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.Texture2DSurface.Alignment = PAGE_SIZE;
Data.Texture2DSurface.PitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.LockPitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.MinPitch = GMM_BYTES(32);
Data.Texture2DSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.Texture2DSurface.MinAllocationSize = PAGE_SIZE;
Data.Texture2DSurface.MinHeight = GMM_SCANLINES(1);
Data.Texture2DSurface.MinWidth = GMM_PIXELS(1);
Data.Texture2DSurface.MinDepth = 0;
Data.Texture2DSurface.MaxHeight = GMM_KBYTE(16);
Data.Texture2DSurface.MaxWidth = GMM_KBYTE(16);
Data.Texture2DSurface.MaxDepth = GMM_FIELD_NA;
Data.Texture2DSurface.MaxArraySize = GMM_KBYTE(2);
{
// Linear surfaces accessed with Media Block Read/Write commands
// require 64-byte-aligned pitch. Such commands only operate on 2D
// resources, so we'll handle the requirement here. Though requirement
// applies to linear surfaces only, our up'ing the pitch alignment to
// 64 bytes here won't affect tiled surfaces, since their pitch
// alignment is never smaller than that.
Data.Texture2DLinearSurface = Data.Texture2DSurface;
Data.Texture2DLinearSurface.PitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.PitchAlignment);
Data.Texture2DLinearSurface.LockPitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.LockPitchAlignment);
Data.Texture2DLinearSurface.RenderPitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.RenderPitchAlignment);
}
// --------------------------
// AsyncFlip Restriction. Register Ref: PRI_STRIDE, PRI_SURF, SRCSZ <-- TODO(Minor): SRCSZ correct reg for W/H req's?
// --------------------------
Data.ASyncFlipSurface.Alignment = GMM_KBYTE(256);
Data.ASyncFlipSurface.PitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.RenderPitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.LockPitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.MinPitch = GMM_BYTES(64);
Data.ASyncFlipSurface.MaxPitch = Data.Texture2DSurface.MaxPitch;
Data.ASyncFlipSurface.MinAllocationSize = PAGE_SIZE;
Data.ASyncFlipSurface.MinHeight = GMM_SCANLINES(1);
Data.ASyncFlipSurface.MinWidth = GMM_PIXELS(1);
Data.ASyncFlipSurface.MinDepth = 0;
Data.ASyncFlipSurface.MaxHeight = Data.Texture2DSurface.MaxHeight; // Beyond DE requirements-Necessary for mosaic framebuffers
Data.ASyncFlipSurface.MaxWidth = Data.Texture2DSurface.MaxWidth; // Okay since GMM isn't actual display requirement gatekeeper.
Data.ASyncFlipSurface.MaxDepth = 1;
Data.ASyncFlipSurface.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Hardware MBM Restriction.
// --------------------------
Data.HardwareMBM = Data.ASyncFlipSurface;
// --------------------------
// Video Buffer Restriction
// --------------------------
Data.Video = Data.Texture2DLinearSurface;
// --------------------------
// Overlay Buffer Restriction. Overlay buffer restriction will be same as Async flip surface since CNL has universal planes.
// --------------------------
Data.Overlay = Data.ASyncFlipSurface;
// --------------------------
// RT & CubeSurface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.CubeSurface.Alignment = PAGE_SIZE;
Data.CubeSurface.PitchAlignment = GMM_BYTES(32);
Data.CubeSurface.LockPitchAlignment = GMM_BYTES(32);
Data.CubeSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.CubeSurface.MinPitch = GMM_BYTES(32);
Data.CubeSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.CubeSurface.MinAllocationSize = PAGE_SIZE;
Data.CubeSurface.MinHeight = GMM_SCANLINES(1);
Data.CubeSurface.MinWidth = GMM_PIXELS(1);
Data.CubeSurface.MinDepth = 0;
Data.CubeSurface.MaxHeight = GMM_KBYTE(16);
Data.CubeSurface.MaxWidth = GMM_KBYTE(16);
Data.CubeSurface.MaxDepth = 1;
Data.CubeSurface.MaxArraySize = GMM_KBYTE(2) / 6; // MaxElements / Cubefaces
// --------------------------
// RT & 3D Surface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.Texture3DSurface.Alignment = PAGE_SIZE;
Data.Texture3DSurface.PitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.LockPitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.MinPitch = GMM_BYTES(32);
Data.Texture3DSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.Texture3DSurface.MinAllocationSize = PAGE_SIZE;
Data.Texture3DSurface.MinHeight = GMM_SCANLINES(1);
Data.Texture3DSurface.MinWidth = GMM_PIXELS(1);
Data.Texture3DSurface.MinDepth = 0;
Data.Texture3DSurface.MaxHeight = GMM_KBYTE(16);
Data.Texture3DSurface.MaxWidth = GMM_KBYTE(16);
Data.Texture3DSurface.MaxDepth = GMM_KBYTE(2);
Data.Texture3DSurface.MaxArraySize = GMM_FIELD_NA;
// --------------------------
// RT & Buffer Type restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.BufferType.Alignment = PAGE_SIZE;
Data.BufferType.PitchAlignment = GMM_BYTES(32);
Data.BufferType.LockPitchAlignment = GMM_BYTES(32);
Data.BufferType.RenderPitchAlignment = GMM_BYTES(32);
Data.BufferType.MinPitch = GMM_BYTES(32);
Data.BufferType.MaxPitch = GMM_GBYTE(256);
Data.BufferType.MinAllocationSize = PAGE_SIZE;
Data.BufferType.MinHeight = GMM_SCANLINES(0);
Data.BufferType.MinWidth = GMM_PIXELS(1);
Data.BufferType.MinDepth = 0;
Data.BufferType.MaxHeight = GMM_SCANLINES(1);
Data.BufferType.MaxWidth = GMM_GBYTE(256);
Data.BufferType.MaxDepth = GMM_FIELD_NA;
Data.BufferType.MaxArraySize = GMM_GBYTE(2);
// --------------------------
// Cursor surface restricion. Register Ref: CURACNTR, CURABASE
// --------------------------
Data.Cursor.Alignment = pGmmLibContext->GetWaTable().WaCursor16K ? GMM_KBYTE(16) : PAGE_SIZE;
Data.Cursor.PitchAlignment = 1;
Data.Cursor.LockPitchAlignment = 1;
Data.Cursor.RenderPitchAlignment = 1;
Data.Cursor.MinPitch = 1;
Data.Cursor.MaxPitch = 0xffffffff;
Data.Cursor.MinAllocationSize = 1;
Data.Cursor.MinHeight = GMM_SCANLINES(1);
Data.Cursor.MinWidth = 1;
Data.Cursor.MinDepth = 0;
Data.Cursor.MaxHeight = 0xffffffff;
Data.Cursor.MaxWidth = 0xffffffff;
Data.Cursor.MaxDepth = 0xffffffff;
Data.Cursor.MaxArraySize = 1;
// clang-format off
/******************************************************************************************************/
/*************************************** Width, Height, Depth, MtsWidth, MtsHeight, MtsDepth */
/******************************************************************************************************/
// Legacy TILE_X/Y
SET_TILE_MODE_INFO(LEGACY_TILE_X, 512, 8, 1, 0, 0, 0)
SET_TILE_MODE_INFO(LEGACY_TILE_Y, 128, 32, 1, 0, 0, 0)
// YS 1D
SET_TILE_MODE_INFO(TILE_YS_1D_128bpe, 4096, 1, 1, 1024, 1, 1)
SET_TILE_MODE_INFO(TILE_YS_1D_64bpe, 8192, 1, 1, 2048, 1, 1)
SET_TILE_MODE_INFO(TILE_YS_1D_32bpe, 16384, 1, 1, 4096, 1, 1)
SET_TILE_MODE_INFO(TILE_YS_1D_16bpe, 32768, 1, 1, 8192, 1, 1)
SET_TILE_MODE_INFO(TILE_YS_1D_8bpe, 65536, 1, 1, 16384, 1, 1)
// YS 2D
SET_TILE_MODE_INFO(TILE_YS_2D_128bpe, 1024, 64, 1, 32, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_64bpe, 1024, 64, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_32bpe, 512, 128, 1, 64, 128, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16bpe, 512, 128, 1, 128, 128, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8bpe, 256, 256, 1, 128, 256, 1)
// YS 2D 2X
SET_TILE_MODE_INFO(TILE_YS_2D_2X_128bpe, 512, 64, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_2X_64bpe, 512, 64, 1, 64, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_2X_32bpe, 256, 128, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_2X_16bpe, 256, 128, 1, 128, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_2X_8bpe, 128, 256, 1, 128, 128, 1)
// YS 2D 4X
SET_TILE_MODE_INFO(TILE_YS_2D_4X_128bpe, 512, 32, 1, 16, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_4X_64bpe, 512, 32, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_4X_32bpe, 256, 64, 1, 32, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_4X_16bpe, 256, 64, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_4X_8bpe, 128, 128, 1, 64, 128, 1)
// YS 2D 8X
SET_TILE_MODE_INFO(TILE_YS_2D_8X_128bpe, 256, 32, 1, 16, 16, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8X_64bpe, 256, 32, 1, 32, 16, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8X_32bpe, 128, 64, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8X_16bpe, 128, 64, 1, 64, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8X_8bpe, 64, 128, 1, 64, 64, 1)
// YS 2D 16X
SET_TILE_MODE_INFO(TILE_YS_2D_16X_128bpe, 256, 16, 1, 8, 16, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16X_64bpe, 256, 16, 1, 16, 16, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16X_32bpe, 128, 32, 1, 16, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16X_16bpe, 128, 32, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16X_8bpe, 64, 64, 1, 32, 64, 1)
// YS 3D
SET_TILE_MODE_INFO(TILE_YS_3D_128bpe, 256, 16, 16, 8, 16, 16)
SET_TILE_MODE_INFO(TILE_YS_3D_64bpe, 256, 16, 16, 16, 16, 16)
SET_TILE_MODE_INFO(TILE_YS_3D_32bpe, 128, 32, 16, 16, 32, 16)
SET_TILE_MODE_INFO(TILE_YS_3D_16bpe, 64, 32, 32, 16, 32, 32)
SET_TILE_MODE_INFO(TILE_YS_3D_8bpe, 64, 32, 32, 32, 32, 32)
// YF 1D
SET_TILE_MODE_INFO(TILE_YF_1D_128bpe, 256, 1, 1, 64, 1, 1)
SET_TILE_MODE_INFO(TILE_YF_1D_64bpe, 512, 1, 1, 128, 1, 1)
SET_TILE_MODE_INFO(TILE_YF_1D_32bpe, 1024, 1, 1, 256, 1, 1)
SET_TILE_MODE_INFO(TILE_YF_1D_16bpe, 2048, 1, 1, 512, 1, 1)
SET_TILE_MODE_INFO(TILE_YF_1D_8bpe, 4096, 1, 1, 1024, 1, 1)
// YF 2D
SET_TILE_MODE_INFO(TILE_YF_2D_128bpe, 256, 16, 1, 8, 16, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_64bpe, 256, 16, 1, 16, 16, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_32bpe, 128, 32, 1, 16, 32, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_16bpe, 128, 32, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_8bpe, 64, 64, 1, 32, 64, 1)
// YF 2D 2X
SET_TILE_MODE_INFO(TILE_YF_2D_2X_128bpe, 128, 16, 1, 4, 8, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_2X_64bpe, 128, 16, 1, 8, 8, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_2X_32bpe, 64, 32, 1, 8, 16, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_2X_16bpe, 64, 32, 1, 16, 16, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_2X_8bpe, 32, 64, 1, 16, 32, 1)
// YF 2D 4X
SET_TILE_MODE_INFO(TILE_YF_2D_4X_128bpe, 128, 8, 1, 4, 4, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_4X_64bpe, 128, 8, 1, 8, 4, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_4X_32bpe, 64, 16, 1, 8, 8, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_4X_16bpe, 64, 16, 1, 16, 8, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_4X_8bpe, 32, 32, 1, 16, 16, 1)
// YF 2D 8X
SET_TILE_MODE_INFO(TILE_YF_2D_8X_128bpe, 64, 8, 1, 4, 4, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_8X_64bpe, 64, 8, 1, 8, 4, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_8X_32bpe, 32, 16, 1, 8, 8, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_8X_16bpe, 32, 16, 1, 16, 8, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_8X_8bpe, 16, 32, 1, 16, 16, 1)
// YF 2D 16X
SET_TILE_MODE_INFO(TILE_YF_2D_16X_128bpe, 64, 4, 1, 1, 4, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_16X_64bpe, 64, 4, 1, 2, 4, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_16X_32bpe, 32, 8, 1, 4, 4, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_16X_16bpe, 32, 8, 1, 8, 4, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_16X_8bpe, 16, 16, 1, 8, 4, 1)
// YF 3D
SET_TILE_MODE_INFO(TILE_YF_3D_128bpe, 64, 8, 8, 4, 4, 8)
SET_TILE_MODE_INFO(TILE_YF_3D_64bpe, 64, 8, 8, 8, 4, 8)
SET_TILE_MODE_INFO(TILE_YF_3D_32bpe, 32, 16, 8, 8, 8, 8)
SET_TILE_MODE_INFO(TILE_YF_3D_16bpe, 16, 16, 16, 8, 8, 16)
SET_TILE_MODE_INFO(TILE_YF_3D_8bpe, 16, 16, 16, 16, 8, 16)
// clang-format on
//--------------------------
// Fence paramaters. Register Ref: FENCE
//--------------------------
Data.NumberFenceRegisters = pGmmLibContext->GetWaTable().Wa16TileFencesOnly ? 16 : 32;
Data.FenceLowBoundShift = 12;
Data.FenceLowBoundMask = GFX_MASK(12, 31);
Data.MinFenceSize = GMM_MBYTE(1);
Data.PagingBufferPrivateDataSize = GMM_KBYTE(4);
Data.MaxLod = 14; // [0,14] --> 15 Total
Data.FBCRequiredStolenMemorySize = GMM_MBYTE(8);
// --------------------------
// Surface Alignment Units
// --------------------------
Data.TexAlign.CCS.Align.Width = 128;
Data.TexAlign.CCS.Align.Height = 64;
Data.TexAlign.CCS.MaxPitchinTiles = 512;
Data.TexAlign.Compressed.Width = 4; // No reason for > HALIGN_4.
Data.TexAlign.Compressed.Height = 4; // No reason for > VALIGN_4.
Data.TexAlign.Compressed.Depth = 4; // No reason for > DALIGN_4.
Data.TexAlign.Depth.Width = 4; // See usage for 16bpp HALIGN_8 special-casing.
Data.TexAlign.Depth.Height = 4;
Data.TexAlign.Depth_D16_UNORM_1x_4x_16x.Width = 8;
Data.TexAlign.Depth_D16_UNORM_1x_4x_16x.Height = Data.TexAlign.Depth.Height;
Data.TexAlign.Depth_D16_UNORM_2x_8x.Width = 8;
Data.TexAlign.Depth_D16_UNORM_2x_8x.Height = Data.TexAlign.Depth.Height;
Data.TexAlign.SeparateStencil.Width = 8;
Data.TexAlign.SeparateStencil.Height = 8;
Data.TexAlign.YUV422.Width = 4;
Data.TexAlign.YUV422.Height = 4;
Data.TexAlign.AllOther.Width = 16; // HALIGN_16 required for non-MSAA RT's for CCS Fast-Clear and...TBA
Data.TexAlign.AllOther.Height = 4; // VALIGN_4 should be sufficent.
Data.TexAlign.XAdapter.Height = D3DKMT_CROSS_ADAPTER_RESOURCE_HEIGHT_ALIGNMENT;
Data.TexAlign.XAdapter.Width = 1; //minimum should be one.
// ----------------------------------
// SURFACE_STATE YOffset Granularity
// ----------------------------------
Data.SurfaceStateYOffsetGranularity = 4;
Data.SamplerFetchGranularityHeight = 4;
Data.SamplerFetchGranularityWidth = 4;
// ----------------------------------
// Restrictions for Cross adapter resource
// ----------------------------------
Data.XAdapter.Alignment = GMM_KBYTE(64); //64KB for DX12/StdSwizzle—-Not worth special-casing.
Data.XAdapter.PitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.RenderPitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.LockPitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.MinPitch = GMM_BYTES(32);
Data.XAdapter.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.XAdapter.MinAllocationSize = PAGE_SIZE;
Data.XAdapter.MinHeight = GMM_SCANLINES(1);
Data.XAdapter.MinWidth = GMM_PIXELS(1);
Data.XAdapter.MinDepth = 0;
Data.XAdapter.MaxHeight = GMM_KBYTE(16);
Data.XAdapter.MaxWidth = GMM_KBYTE(16);
Data.XAdapter.MaxDepth = GMM_FIELD_NA;
Data.XAdapter.MaxArraySize = GMM_KBYTE(2);
//---------------------------------------------
//MaxSize for any surface type
//---------------------------------------------
Data.SurfaceMaxSize = GMM_GBYTE(256);
Data.MaxGpuVirtualAddressBitsPerResource = 38;
Data.HiZPixelsPerByte = 2;
Data.ReconMaxHeight = Data.Texture2DSurface.MaxHeight; // Reconstructed surfaces require more height and width for higher resolutions.
Data.ReconMaxWidth = Data.Texture2DSurface.MaxWidth;
Data.NoOfBitsSupported = 39;
Data.HighestAcceptablePhysicalAddress = GFX_MASK_LARGE(0, 38);
}

View File

@ -0,0 +1,155 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "Internal/Common/Platform/GmmGen10Platform.h"
#include "Internal/Common/Platform/GmmGen11Platform.h"
GmmLib::PlatformInfoGen11::PlatformInfoGen11(PLATFORM &Platform, Context *pGmmLibContext)
: PlatformInfoGen10(Platform, pGmmLibContext)
{
Data.SurfaceMaxSize = GMM_GBYTE(16384);
Data.MaxGpuVirtualAddressBitsPerResource = 44;
//Override the Height VP9 VdEnc requirement for Gen11 8k resolution.
Data.ReconMaxHeight = GMM_KBYTE(32);
//Override CCS MaxPitch requirement
if(GFX_GET_CURRENT_PRODUCT(Data.Platform) == IGFX_ICELAKE)
{
Data.TexAlign.CCS.MaxPitchinTiles = 1024;
}
if(GFX_GET_CURRENT_PRODUCT(Data.Platform) == IGFX_LAKEFIELD)
{
Data.SurfaceMaxSize = GMM_GBYTE(64);
Data.MaxGpuVirtualAddressBitsPerResource = 36;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Validates the MMC parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @param[in] GMM_TEXTURE_INFO which specify what sort of resource to create
/// @return 1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::PlatformInfoGen11::ValidateMMC(GMM_TEXTURE_INFO &Surf)
{
if(Surf.Flags.Gpu.MMC && //For Media Memory Compression --
((!(GMM_IS_4KB_TILE(Surf.Flags) || GMM_IS_64KB_TILE(Surf.Flags))) ||
Surf.ArraySize > GMM_MAX_MMC_INDEX))
{
return 0;
}
if(GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_LAKEFIELD)
{
if(Surf.Flags.Gpu.MMC &&
Surf.Flags.Gpu.UnifiedAuxSurface &&
!(Surf.Flags.Info.TiledY &&
(Surf.Format == GMM_FORMAT_NV12 || GmmIsP0xx(Surf.Format))))
{
GMM_ASSERTDPF(0, "Invalid MMC usage for LKF!");
return 0;
}
}
return 1;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Validates the UnifiedAuxSurface parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @param[in] GMM_TEXTURE_INFO which specify what sort of resource to create
/// @return 1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::PlatformInfoGen11::ValidateUnifiedAuxSurface(GMM_TEXTURE_INFO &Surf)
{
if((Surf.Flags.Gpu.UnifiedAuxSurface) &&
!( //--- Legitimate UnifiedAuxSurface Case ------------------------------------------
Surf.Flags.Gpu.CCS &&
((Surf.MSAA.NumSamples <= 1 && (Surf.Flags.Gpu.RenderTarget || Surf.Flags.Gpu.Texture))) ||
((GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_LAKEFIELD) && Surf.Flags.Gpu.MMC &&
(Surf.MSAA.NumSamples <= 1))))
{
GMM_ASSERTDPF(0, "Invalid UnifiedAuxSurface usage!");
return 0;
}
return 1;
}
//=============================================================================
//
// Function: CheckFmtDisplayDecompressible
//
// Desc: Returns true if display hw supports lossless render/media decompression
// else returns false.
// Umds can call it to decide if full resolve is required
//
// Parameters:
// See function arguments.
//
// Returns:
// uint8_t
//-----------------------------------------------------------------------------
uint8_t GmmLib::PlatformInfoGen11::CheckFmtDisplayDecompressible(GMM_TEXTURE_INFO &Surf,
bool IsSupportedRGB64_16_16_16_16,
bool IsSupportedRGB32_8_8_8_8,
bool IsSupportedRGB32_2_10_10_10,
bool IsSupportedMediaFormats)
{
bool IsRenderCompressed = false;
bool IsMediaCompressed = false;
GMM_UNREFERENCED_PARAMETER(IsSupportedMediaFormats);
if(GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_LAKEFIELD)
{
if(Surf.Flags.Gpu.MMC &&
Surf.Flags.Info.TiledY &&
(Surf.Format == GMM_FORMAT_NV12 ||
Surf.Format == GMM_FORMAT_P010))
{
IsMediaCompressed = true;
}
if(IsSupportedRGB64_16_16_16_16 || //RGB64 16:16 : 16 : 16 FP16
IsSupportedRGB32_8_8_8_8 || //RGB32 8 : 8 : 8 : 8
IsSupportedRGB32_2_10_10_10) //RGB32 2 : 10 : 10 : 10
{
IsRenderCompressed = true;
}
}
else
{
// Pre-LKF1
if(IsSupportedRGB32_8_8_8_8 || //RGB32 8 : 8 : 8 : 8
(GFX_GET_CURRENT_PRODUCT(pGmmLibContext->GetPlatformInfo().Platform) == IGFX_ICELAKE &&
IsSupportedRGB64_16_16_16_16)) //RGB64 16:16 : 16 : 16 FP16
{
IsRenderCompressed = true;
}
}
return IsRenderCompressed || IsMediaCompressed;
}

View File

@ -0,0 +1,595 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "Internal/Common/Platform/GmmGen12Platform.h"
/************************ RT->CCS Sizing definitions ************************
H/V/D Align and Downscale factor to obtain CCS from given RT dimensions
Restrictions:
CCS's RT (2D/3D YF) alignment to 4x1 (2D/3D YF) pages sharing 1x1 Aux$line
(2D YS) 2x2 ( 2D YF) pages "
(3D YS) 2x1x2 ( 3D YF) pages " ie Slices share Aux$line
(Color MSAA'd YF) 4x1 (MSAA'dYF) pages " ie all samples share Aux$line (Samples are array'd ie YF 4KB = YF-MSAA x MSAA-Samples)
(Color MSAA 2x/4x YS) 2x2x1 ( 2D YF) pages " ie Single sample per Aux$line
(Color MSAA 8x YS) 1x2x2 ( 2D YF) pages " ie 2 samples share Aux$line
(Color MSAA 16x YS) 1x1x4 ( 2D YF) pages " ie 4 samples share Aux$line
(Depth MSAA YF) 4x1 ( 2D YF) pages " ie all samples share Aux$line
(Depth MSAA 2x/4x YS) 2x2x1 ( 2D YF) pages " ie Single sample per Aux$line
(Depth MSAA 8x YS) 1x2x2 ( 2D YF) pages " ie 2 samples share Aux$line
(Depth MSAA 16x YS) 1x1x4 ( 2D YF) pages " ie 4 samples share Aux$line
ie Depth/Color MSAA have common alignment, but due to different pixel packing (Depth MSS is interleaved, Color MSS is arrayed)
SamplePerAux$line samples are X-major (for Depth), while Y-major (for Color) packed ie For Depth MSAA, Hdownscale *=SamplePerAux$line;
for color MSAA, Vdownscale = Vdownscale; for both, MSAA-samples/SamplePerAux$line times sample shared CCS-size
HAlign: Horizontal Align in pixels
VAlign: Vertical Align in pixels
DAlign: Depth Align in pixels
HAlignxVAlignxDAlign [RT size] occupies one Aux$line
SamplesPerAux$line: Samples sharing CCS; NSamples divisor on MSAA-samples giving multiple (on shared CCS) to cover all samples
HDownscale: width divisor on CCSRTAlign`d width
VDownscale: height divisor on CCSRTAlign`d height
Convention:
(+ve) HDownscale/VDownscale are downscale factors, and used as divisors
(-ve) HDownscale/VDownscale are upscale factors, their absolute value used as multipliers
ie if HDownscale etc is smaller than 1, its reciprocal is stored with -ve sign
<---- CCSRTALIGN -----> <-- RT->CCS downscale-->
( TileMode, HAlign , VAlign, DAlign, HDownscale, VDownscale)
or
SamplesPerAux$line,
eg:
CCSRTALIGN(TILE_YF_2D_8bpe, 256, 64, 1, 16, 16 )
**********************************************************************************************************/
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates This function will initialize the necessary info based on platform.
/// - Buffer type restrictions (Eg: Z, Color, Display)
/// - X/Y tile dimensions
///
/// @param[in] Platform: Contains information about platform to initialize an object
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::PlatformInfoGen12::PlatformInfoGen12(PLATFORM &Platform, Context *pGmmLibContext)
: PlatformInfoGen11(Platform, pGmmLibContext)
{
__GMM_ASSERTPTR(pGmmLibContext, VOIDRETURN);
//Compression format update
GMM_RESOURCE_FORMAT GmmFormat;
#define GMM_FORMAT_SKU(FtrXxx) (pGmmLibContext->GetSkuTable().FtrXxx != 0)
#define GMM_COMPR_FORMAT_INVALID ((pGmmLibContext->GetSkuTable().FtrFlatPhysCCS != 0) ? static_cast<uint8_t>(GMM_FLATCCS_FORMAT_INVALID) : static_cast<uint8_t>(GMM_E2ECOMP_FORMAT_INVALID))
#define GMM_FORMAT(Name, bpe, _Width, _Height, _Depth, IsRT, IsASTC, RcsSurfaceFormat, SSCompressionFmt, Availability) \
\
{ \
GmmFormat = GMM_FORMAT_##Name; \
Data.FormatTable[GmmFormat].CompressionFormat.CompressionFormat = static_cast<uint8_t>(SSCompressionFmt); \
}
#include "External/Common/GmmFormatTable.h"
// --------------------------
// Surface Alignment Units
// --------------------------
// 3DSTATE_DEPTH_BUFFER
//======================================================================
// Surf Format | MSAA | HAlign | VAlign |
//======================================================================
// D16_UNORM | 1x, 4x, 16x | 8 | 8 |
// D16_UNORM | 2x, 8x | 16 | 4 |
// Not D16_UNORM | 1x,2x,4x,8x,16x | 8 | 4 |
//======================================================================
// 3DSTATE_STENCIL_BUFFER
//======================================================================
// Surf Format | MSAA | HAlign | VAlign |
//======================================================================
// N/A | N/A | 16 | 8 |
//======================================================================
Data.SurfaceMaxSize = GMM_GBYTE(16384);
Data.MaxGpuVirtualAddressBitsPerResource = 44;
//Override the Height VP9 VdEnc requirement for Gen12 16k resolution.
Data.ReconMaxHeight = GMM_KBYTE(48);
Data.ReconMaxWidth = GMM_KBYTE(32);
if((GFX_GET_CURRENT_PRODUCT(Data.Platform) >= IGFX_DG1))
{
Data.HiZPixelsPerByte = 4;
}
Data.TexAlign.Depth.Width = 8; // Not D16_UNORM
Data.TexAlign.Depth.Height = 4;
Data.TexAlign.Depth_D16_UNORM_1x_4x_16x.Width = 8;
Data.TexAlign.Depth_D16_UNORM_1x_4x_16x.Height = 8;
Data.TexAlign.Depth_D16_UNORM_2x_8x.Width = 16;
Data.TexAlign.Depth_D16_UNORM_2x_8x.Height = 4;
Data.TexAlign.SeparateStencil.Width = 16;
Data.TexAlign.SeparateStencil.Height = 8;
//CCS unit size ie cacheline
Data.TexAlign.CCS.Align.Width = 16;
Data.TexAlign.CCS.Align.Height = 4;
Data.TexAlign.CCS.Align.Depth = 1;
Data.TexAlign.CCS.MaxPitchinTiles = 1024;
// clang-format off
SET_TILE_MODE_INFO(TILE4, 128, 32, 1, 0, 0, 0)
// TILE__64 1D
SET_TILE_MODE_INFO(TILE__64_1D_128bpe, 4096, 1, 1, 1024, 1, 1)
SET_TILE_MODE_INFO(TILE__64_1D_64bpe, 8192, 1, 1, 2048, 1, 1)
SET_TILE_MODE_INFO(TILE__64_1D_32bpe, 16384, 1, 1, 4096, 1, 1)
SET_TILE_MODE_INFO(TILE__64_1D_16bpe, 32768, 1, 1, 8192, 1, 1)
SET_TILE_MODE_INFO(TILE__64_1D_8bpe, 65536, 1, 1, 16384, 1, 1)
// TILE__64 2D
SET_TILE_MODE_INFO(TILE__64_2D_128bpe, 1024, 64, 1, 32, 64, 1)
SET_TILE_MODE_INFO(TILE__64_2D_64bpe, 1024, 64, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE__64_2D_32bpe, 512, 128, 1, 64, 128, 1)
SET_TILE_MODE_INFO(TILE__64_2D_16bpe, 512, 128, 1, 128, 128, 1)
SET_TILE_MODE_INFO(TILE__64_2D_8bpe, 256, 256, 1, 128, 256, 1)
// TILE__64 2D 2X
SET_TILE_MODE_INFO(TILE__64_2D_2X_128bpe, 512, 64, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE__64_2D_2X_64bpe, 512, 64, 1, 64, 32, 1)
SET_TILE_MODE_INFO(TILE__64_2D_2X_32bpe, 256, 128, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE__64_2D_2X_16bpe, 256, 128, 1, 128, 64, 1)
SET_TILE_MODE_INFO(TILE__64_2D_2X_8bpe, 128, 256, 1, 128, 128, 1)
// TILE__64 2D 4X
SET_TILE_MODE_INFO(TILE__64_2D_4X_128bpe, 512, 32, 1, 16, 32, 1)
SET_TILE_MODE_INFO(TILE__64_2D_4X_64bpe, 512, 32, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE__64_2D_4X_32bpe, 256, 64, 1, 32, 64, 1)
SET_TILE_MODE_INFO(TILE__64_2D_4X_16bpe, 256, 64, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE__64_2D_4X_8bpe, 128, 128, 1, 64, 128, 1)
// TILE__64 3D
SET_TILE_MODE_INFO(TILE__64_3D_128bpe, 256, 16, 16, 8, 16, 16)
SET_TILE_MODE_INFO(TILE__64_3D_64bpe, 256, 16, 16, 16, 16, 16)
SET_TILE_MODE_INFO(TILE__64_3D_32bpe, 128, 32, 16, 16, 32, 16)
SET_TILE_MODE_INFO(TILE__64_3D_16bpe, 64, 32, 32, 16, 32, 32)
SET_TILE_MODE_INFO(TILE__64_3D_8bpe, 64, 32, 32, 32, 32, 32)
// clang-format off
//Extended CCS alignment for per bpp/Tiling CCS alignment
#define CCSRTALIGN(TileMode, HAlign, VAlign, DAlign, HDownscale, VDownscale) \
{ \
TexAlignEx.CCSEx[CCS_MODE(TileMode)].Align.Width = HAlign; \
TexAlignEx.CCSEx[CCS_MODE(TileMode)].Align.Height = VAlign; \
TexAlignEx.CCSEx[CCS_MODE(TileMode)].Align.Depth = DAlign; \
TexAlignEx.CCSEx[CCS_MODE(TileMode)].Downscale.Width = HDownscale; \
TexAlignEx.CCSEx[CCS_MODE(TileMode)].Downscale.Height = VDownscale; \
TexAlignEx.CCSEx[CCS_MODE(TileMode)].Downscale.Depth = DAlign; \
}
// clang-format off
//See "RT->CCS Sizing definitions" comments above for explanation on fields
/********* TileMode HAlign, VAlign, DAlign, HDownscale, VDownscale ***/
CCSRTALIGN(TILE_YF_2D_8bpe, 256, 64, 1, 16, 16 );
CCSRTALIGN(TILE_YF_2D_16bpe, 256, 32, 1, 16, 8 );
CCSRTALIGN(TILE_YF_2D_32bpe, 128, 32, 1, 8, 8 );
CCSRTALIGN(TILE_YF_2D_64bpe, 128, 16, 1, 8, 4 );
CCSRTALIGN(TILE_YF_2D_128bpe, 64, 16, 1, 4, 4 );
CCSRTALIGN(TILE_YF_3D_8bpe, 64, 16, 16, 4, 4 );
CCSRTALIGN(TILE_YF_3D_16bpe, 32, 16, 16, 2, 4 );
CCSRTALIGN(TILE_YF_3D_32bpe, 32, 16, 8, 2, 4 );
CCSRTALIGN(TILE_YF_3D_64bpe, 32, 8, 8, 2, 2 );
CCSRTALIGN(TILE_YF_3D_128bpe, 16, 8, 8, 1, 2 );
CCSRTALIGN(TILE_YF_2D_2X_8bpe, 128, 64, 2, 8, 16 );
CCSRTALIGN(TILE_YF_2D_2X_16bpe, 128, 32, 2, 8, 8 );
CCSRTALIGN(TILE_YF_2D_2X_32bpe, 64, 32, 2, 4, 8 );
CCSRTALIGN(TILE_YF_2D_2X_64bpe, 64, 16, 2, 4, 4 );
CCSRTALIGN(TILE_YF_2D_2X_128bpe, 32, 16, 2, 2, 4 );
CCSRTALIGN(TILE_YF_2D_4X_8bpe, 128, 32, 4, 8, 8 );
CCSRTALIGN(TILE_YF_2D_4X_16bpe, 128, 16, 4, 8, 4 );
CCSRTALIGN(TILE_YF_2D_4X_32bpe, 64, 16, 4, 4, 4 );
CCSRTALIGN(TILE_YF_2D_4X_64bpe, 64, 8, 4, 4, 2 );
CCSRTALIGN(TILE_YF_2D_4X_128bpe, 32, 8, 4, 2, 2 );
CCSRTALIGN(TILE_YF_2D_8X_8bpe, 64, 32, 8, 4, 8 );
CCSRTALIGN(TILE_YF_2D_8X_16bpe, 64, 16, 8, 4, 4 );
CCSRTALIGN(TILE_YF_2D_8X_32bpe, 32, 16, 8, 2, 4 );
CCSRTALIGN(TILE_YF_2D_8X_64bpe, 32, 8, 8, 2, 2 );
CCSRTALIGN(TILE_YF_2D_8X_128bpe, 16, 8, 8, 1, 2 );
CCSRTALIGN(TILE_YF_2D_16X_8bpe, 64, 16, 16, 4, 4 );
CCSRTALIGN(TILE_YF_2D_16X_16bpe, 64, 8, 16, 4, 2 );
CCSRTALIGN(TILE_YF_2D_16X_32bpe, 32, 8, 16, 2, 2 );
CCSRTALIGN(TILE_YF_2D_16X_64bpe, 32, 4, 16, 2, 1 );
CCSRTALIGN(TILE_YF_2D_16X_128bpe, 16, 4, 16, 1, 1 );
CCSRTALIGN(TILE_YS_2D_8bpe, 128, 128, 1, 8, 32 );
CCSRTALIGN(TILE_YS_2D_16bpe, 128, 64, 1, 8, 16 );
CCSRTALIGN(TILE_YS_2D_32bpe, 64, 64, 1, 4, 16 );
CCSRTALIGN(TILE_YS_2D_64bpe, 64, 32, 1, 4, 8 );
CCSRTALIGN(TILE_YS_2D_128bpe, 32, 32, 1, 2, 8 );
CCSRTALIGN(TILE_YS_3D_8bpe, 32, 16, 32, 2, 4 );
CCSRTALIGN(TILE_YS_3D_16bpe, 16, 16, 32, 1, 4 );
CCSRTALIGN(TILE_YS_3D_32bpe, 16, 16, 16, 1, 4 );
CCSRTALIGN(TILE_YS_3D_64bpe, 16, 8, 16, 1, 2 );
CCSRTALIGN(TILE_YS_3D_128bpe, 8, 8, 16, -2, 2 );
CCSRTALIGN(TILE_YS_2D_2X_8bpe, 128, 128, 1, 8, 32 );
CCSRTALIGN(TILE_YS_2D_2X_16bpe, 128, 64, 1, 8, 16 );
CCSRTALIGN(TILE_YS_2D_2X_32bpe, 64, 64, 1, 4, 16 );
CCSRTALIGN(TILE_YS_2D_2X_64bpe, 64, 32, 1, 4, 8 );
CCSRTALIGN(TILE_YS_2D_2X_128bpe, 32, 32, 1, 2, 8 );
CCSRTALIGN(TILE_YS_2D_4X_8bpe, 128, 128, 1, 8, 32 );
CCSRTALIGN(TILE_YS_2D_4X_16bpe, 128, 64, 1, 8, 16 );
CCSRTALIGN(TILE_YS_2D_4X_32bpe, 64, 64, 1, 4, 16 );
CCSRTALIGN(TILE_YS_2D_4X_64bpe, 64, 32, 1, 4, 8 );
CCSRTALIGN(TILE_YS_2D_4X_128bpe, 32, 32, 1, 2, 8 );
CCSRTALIGN(TILE_YS_2D_8X_8bpe, 64, 128, 2, 4, 32 );
CCSRTALIGN(TILE_YS_2D_8X_16bpe, 64, 64, 2, 4, 16 );
CCSRTALIGN(TILE_YS_2D_8X_32bpe, 32, 64, 2, 2, 16 );
CCSRTALIGN(TILE_YS_2D_8X_64bpe, 32, 32, 2, 2, 8 );
CCSRTALIGN(TILE_YS_2D_8X_128bpe, 16, 32, 2, 1, 8 );
CCSRTALIGN(TILE_YS_2D_16X_8bpe, 64, 64, 4, 4, 16 );
CCSRTALIGN(TILE_YS_2D_16X_16bpe, 64, 32, 4, 4, 8 );
CCSRTALIGN(TILE_YS_2D_16X_32bpe, 32, 32, 4, 2, 8 );
CCSRTALIGN(TILE_YS_2D_16X_64bpe, 32, 16, 4, 2, 4 );
CCSRTALIGN(TILE_YS_2D_16X_128bpe, 16, 16, 4, 1, 4 );
#undef CCSRTALIGN
// clang-format on
#define FCRECTALIGN(TileMode, bpp, HAlign, VAlign, HDownscale, VDownscale) \
{ \
FCTileMode[FCMode(TileMode, bpp)].Align.Width = HAlign; \
FCTileMode[FCMode(TileMode, bpp)].Align.Height = VAlign; \
FCTileMode[FCMode(TileMode, bpp)].Align.Depth = 1; \
FCTileMode[FCMode(TileMode, bpp)].Downscale.Width = HDownscale; \
FCTileMode[FCMode(TileMode, bpp)].Downscale.Height = VDownscale; \
FCTileMode[FCMode(TileMode, bpp)].Downscale.Depth = 1; \
}
// clang-format off
FCRECTALIGN(LEGACY_TILE_Y , 8, 512, 32, 256, 16);
FCRECTALIGN(LEGACY_TILE_Y , 16, 256, 32, 128, 16);
FCRECTALIGN(LEGACY_TILE_Y , 32, 128, 32, 64, 16);
FCRECTALIGN(LEGACY_TILE_Y , 64, 64, 32, 32, 16);
FCRECTALIGN(LEGACY_TILE_Y , 128, 32, 32, 16, 16);
FCRECTALIGN(TILE_YF_2D_8bpe , 8, 256, 64, 128, 32);
FCRECTALIGN(TILE_YF_2D_16bpe , 16, 256, 32, 128, 16);
FCRECTALIGN(TILE_YF_2D_32bpe , 32, 128, 32, 64, 16);
FCRECTALIGN(TILE_YF_2D_64bpe , 64, 128, 16, 64, 8);
FCRECTALIGN(TILE_YF_2D_128bpe, 128, 64, 16, 32, 8);
FCRECTALIGN(TILE_YS_2D_8bpe , 8, 128, 128, 64, 64);
FCRECTALIGN(TILE_YS_2D_16bpe , 16, 128, 64, 64, 32);
FCRECTALIGN(TILE_YS_2D_32bpe , 32, 64, 64, 32, 32);
FCRECTALIGN(TILE_YS_2D_64bpe , 64, 64, 32, 32, 16);
FCRECTALIGN(TILE_YS_2D_128bpe, 128, 32, 32, 16, 16);
FCRECTALIGN(TILE4 , 8, 1024, 16, 1024, 16);
FCRECTALIGN(TILE4 , 16, 512, 16, 512, 16);
FCRECTALIGN(TILE4 , 32, 256, 16, 256, 16);
FCRECTALIGN(TILE4 , 64, 128, 16, 128, 16);
FCRECTALIGN(TILE4 , 128, 64, 16, 64, 16);
FCRECTALIGN(TILE__64_2D_8bpe , 8, 128, 128, 128, 128);
FCRECTALIGN(TILE__64_2D_16bpe , 16, 128, 64, 128, 64);
FCRECTALIGN(TILE__64_2D_32bpe , 32, 64, 64, 64, 64);
FCRECTALIGN(TILE__64_2D_64bpe , 64, 64, 32, 64, 32);
FCRECTALIGN(TILE__64_2D_128bpe, 128, 32, 32, 32, 32);
#undef FCRECTALIGN
// clang-format on
Data.NoOfBitsSupported = 39;
Data.HighestAcceptablePhysicalAddress = GFX_MASK_LARGE(0, 38);
if(GFX_GET_CURRENT_PRODUCT(Data.Platform) == IGFX_PVC)
{
Data.NoOfBitsSupported = 52;
Data.HighestAcceptablePhysicalAddress = GFX_MASK_LARGE(0, 51);
}
else if(GFX_GET_CURRENT_PRODUCT(Data.Platform) == IGFX_ALDERLAKE_S ||
(GFX_GET_CURRENT_PRODUCT(Data.Platform) == IGFX_ALDERLAKE_P) ||
(GFX_GET_CURRENT_PRODUCT(Data.Platform) == IGFX_ALDERLAKE_N) ||
(GFX_GET_CURRENT_PRODUCT(Data.Platform) >= IGFX_XE_HP_SDV))
{
Data.NoOfBitsSupported = 46;
Data.HighestAcceptablePhysicalAddress = GFX_MASK_LARGE(0, 45);
}
}
void GmmLib::PlatformInfoGen12::ApplyExtendedTexAlign(uint32_t CCSMode, ALIGNMENT &UnitAlign)
{
if(CCSMode < CCS_MODES)
{
UnitAlign.Width = TexAlignEx.CCSEx[CCSMode].Align.Width;
UnitAlign.Height = TexAlignEx.CCSEx[CCSMode].Align.Height;
UnitAlign.Depth = TexAlignEx.CCSEx[CCSMode].Align.Depth;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Copies parameters or sets flags based on info sent by the client.
///
/// @param[in] CreateParams: Flags which specify what sort of resource to create
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::PlatformInfoGen12::SetCCSFlag(GMM_RESOURCE_FLAG &Flags)
{
if(Flags.Gpu.MMC)
{
Flags.Gpu.CCS = Flags.Gpu.MMC;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Validates the MMC parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @param[in] GMM_TEXTURE_INFO which specify what sort of resource to create
/// @return 1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::PlatformInfoGen12::ValidateMMC(GMM_TEXTURE_INFO &Surf)
{
if(Surf.Flags.Gpu.MMC && //For Media Memory Compression --
(!(GMM_IS_4KB_TILE(Surf.Flags) || GMM_IS_64KB_TILE(Surf.Flags)) &&
(!Surf.Flags.Gpu.__NonMsaaLinearCCS)))
{
return 0;
}
return 1;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Validates the parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @param[in] GMM_TEXTURE_INFO which specify what sort of resource to create
/// @return 1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::PlatformInfoGen12::ValidateCCS(GMM_TEXTURE_INFO &Surf)
{
if(!( //--- Legitimate CCS Case ----------------------------------------
((Surf.Type >= RESOURCE_2D && Surf.Type <= RESOURCE_BUFFER) && ////Not supported: 1D; Supported: Buffer, 2D, 3D, cube, Arrays, mip-maps, MSAA, Depth/Stencil
(!(Surf.Flags.Info.RenderCompressed || Surf.Flags.Info.MediaCompressed) || //Not compressed surface eg separate Aux Surf
(GMM_IS_4KB_TILE(Surf.Flags) || GMM_IS_64KB_TILE(Surf.Flags)) || //Only on Y/Ys
(Surf.Flags.Info.Linear && Surf.Type == RESOURCE_BUFFER && //Machine-Learning compression on untyped linear buffer
Surf.Flags.Info.RenderCompressed)))))
{
GMM_ASSERTDPF(0, "Invalid CCS usage!");
return 0;
}
//Compressed resource (main surf) must pre-define MC/RC type
if(!(Surf.Flags.Gpu.__NonMsaaTileYCcs || Surf.Flags.Gpu.__NonMsaaLinearCCS) &&
!Surf.Flags.Gpu.ProceduralTexture &&
!(Surf.Flags.Info.RenderCompressed || Surf.Flags.Info.MediaCompressed))
{
GMM_ASSERTDPF(0, "Invalid CCS usage - RC/MC type unspecified!");
return 0;
}
if(Surf.Flags.Info.RenderCompressed && Surf.Flags.Info.MediaCompressed)
{
GMM_ASSERTDPF(0, "Invalid CCS usage - can't be both RC and MC!");
return 0;
}
if(!pGmmLibContext->GetSkuTable().FtrLinearCCS &&
(Surf.Type == RESOURCE_3D || Surf.MaxLod > 0 || Surf.MSAA.NumSamples > 1 ||
!(Surf.Flags.Info.TiledYf || GMM_IS_64KB_TILE(Surf.Flags))))
{
GMM_ASSERTDPF(0, "CCS support for (volumetric, mip'd, MSAA'd, TileY) resources only enabled with Linear CCS!");
return 0;
}
GMM_ASSERTDPF((Surf.Flags.Wa.PreGen12FastClearOnly == 0), "FastClear Only unsupported on Gen12+!");
Surf.Flags.Wa.PreGen12FastClearOnly = 0;
return 1;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Validates the UnifiedAuxSurface parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @param[in] GMM_TEXTURE_INFO which specify what sort of resource to create
/// @return 1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::PlatformInfoGen12::ValidateUnifiedAuxSurface(GMM_TEXTURE_INFO &Surf)
{
if((Surf.Flags.Gpu.UnifiedAuxSurface) &&
!( //--- Legitimate UnifiedAuxSurface Case ------------------------------------------
Surf.Flags.Gpu.CCS &&
((Surf.MSAA.NumSamples <= 1 && (Surf.Flags.Gpu.RenderTarget || Surf.Flags.Gpu.Texture)) ||
((Surf.Flags.Gpu.Depth || Surf.Flags.Gpu.SeparateStencil || Surf.MSAA.NumSamples > 1)))))
{
GMM_ASSERTDPF(0, "Invalid UnifiedAuxSurface usage!");
return 0;
}
return 1;
}
//=============================================================================
//
// Function: CheckFmtDisplayDecompressible
//
// Desc: Returns true if display hw supports lossless render/media decompression
// else returns false. Restrictions are from
// Umds can call it to decide if full resolve is required
//
// Parameters:
// See function arguments.
//
// Returns:
// uint8_t
//-----------------------------------------------------------------------------
uint8_t GmmLib::PlatformInfoGen12::CheckFmtDisplayDecompressible(GMM_TEXTURE_INFO &Surf,
bool IsSupportedRGB64_16_16_16_16,
bool IsSupportedRGB32_8_8_8_8,
bool IsSupportedRGB32_2_10_10_10,
bool IsSupportedMediaFormats)
{
//Check fmt is display decompressible
if(((Surf.Flags.Info.RenderCompressed || Surf.Flags.Info.MediaCompressed) &&
(IsSupportedRGB64_16_16_16_16 || //RGB64 16:16 : 16 : 16 FP16
IsSupportedRGB32_8_8_8_8 || //RGB32 8 : 8 : 8 : 8
IsSupportedRGB32_2_10_10_10)) || //RGB32 2 : 10 : 10 : 10) ||
(Surf.Flags.Info.MediaCompressed && IsSupportedMediaFormats)) //YUV444 - Y412, Y416
{
//Display supports compression on TileY, but not Yf/Ys (deprecated for display support)
if(GMM_IS_4KB_TILE(Surf.Flags) &&
!(Surf.Flags.Info.TiledYf || GMM_IS_64KB_TILE(Surf.Flags)))
{
return true;
}
}
return false;
}
//=============================================================================
//
// Function: OverrideCompressionFormat
//
// Desc: SurfaceState compression format encoding differ for MC vs RC on few formats. This function
// overrides default RC encoding for MC requests
//
// Parameters:
// See function arguments.
//
// Returns:
// uint8_t
//-----------------------------------------------------------------------------
uint8_t GmmLib::PlatformInfoGen12::OverrideCompressionFormat(GMM_RESOURCE_FORMAT Format, uint8_t IsMC)
{
uint8_t CompressionFormat = Data.FormatTable[Format].CompressionFormat.CompressionFormat;
if(pGmmLibContext->GetSkuTable().FtrFlatPhysCCS || pGmmLibContext->GetSkuTable().FtrUnified3DMediaCompressionFormats)
{
if(!IsMC &&
!pGmmLibContext->GetSkuTable().FtrUnified3DMediaCompressionFormats &&
(CompressionFormat < GMM_FLATCCS_MIN_RC_FORMAT ||
CompressionFormat > GMM_FLATCCS_MAX_RC_FORMAT))
{
CompressionFormat = GMM_FLATCCS_FORMAT_INVALID;
}
if(!IsMC &&
pGmmLibContext->GetSkuTable().FtrUnified3DMediaCompressionFormats &&
(CompressionFormat < GMM_UNIFIED_COMP_MIN_RC_FORMAT ||
CompressionFormat > GMM_UNIFIED_COMP_MAX_RC_FORMAT))
{
CompressionFormat = GMM_UNIFIED_COMP_FORMAT_INVALID;
}
else if(IsMC)
{
if(!pGmmLibContext->GetSkuTable().FtrUnified3DMediaCompressionFormats)
{
if(CompressionFormat >= GMM_FLATCCS_MIN_MC_FORMAT && CompressionFormat <= GMM_FLATCCS_MAX_MC_FORMAT)
{
//True MC format encodings, drop MC-identify bit (ie bit5)
CompressionFormat -= (GMM_FLATCCS_MIN_MC_FORMAT - 1);
}
else
{
// RC format encoding, needs MC format encoding for MC usage
switch(CompressionFormat)
{
case GMM_FLATCCS_FORMAT_RGB10A2:
CompressionFormat = GMM_FLATCCS_FORMAT_RGB10b;
break;
case GMM_FLATCCS_FORMAT_RGBA16U:
CompressionFormat = GMM_FLATCCS_FORMAT_RGBA16_MEDIA;
break;
case GMM_FLATCCS_FORMAT_RGBA8U:
CompressionFormat = GMM_FLATCCS_FORMAT_ARGB8b;
break;
default:
if(CompressionFormat < GMM_FLATCCS_MIN_MC_FORMAT || CompressionFormat > GMM_FLATCCS_MAX_MC_FORMAT)
{
CompressionFormat = GMM_FLATCCS_FORMAT_INVALID;
}
break;
}
if(CompressionFormat != GMM_FLATCCS_FORMAT_INVALID)
{
//drop MC-identify bit (ie bit 5)
CompressionFormat -= (GMM_FLATCCS_MIN_MC_FORMAT - 1);
}
}
}
else
{
if(CompressionFormat >= GMM_UNIFIED_COMP_MIN_MC_FORMAT && CompressionFormat <= GMM_UNIFIED_COMP_MAX_MC_FORMAT)
{
//True MC format encodings, drop MC-identify bit (ie bit5)
CompressionFormat -= (GMM_UNIFIED_COMP_MIN_MC_FORMAT - 1);
}
else
{
// RC format encoding, needs MC format encoding for MC usage
switch(CompressionFormat)
{
case GMM_UNIFIED_COMP_FORMAT_RGB10A2:
CompressionFormat = GMM_UNIFIED_COMP_FORMAT_RGB10b;
break;
case GMM_UNIFIED_COMP_FORMAT_RGBA16U:
case GMM_UNIFIED_COMP_FORMAT_RGBA16F:
CompressionFormat = GMM_UNIFIED_COMP_FORMAT_RGBA16_MEDIA;
break;
case GMM_UNIFIED_COMP_FORMAT_RGBA8U:
case GMM_UNIFIED_COMP_FORMAT_RGBA8S:
CompressionFormat = GMM_UNIFIED_COMP_FORMAT_ARGB8b;
break;
default:
if(CompressionFormat < GMM_UNIFIED_COMP_MIN_MC_FORMAT || CompressionFormat > GMM_UNIFIED_COMP_MAX_MC_FORMAT)
{
CompressionFormat = GMM_UNIFIED_COMP_FORMAT_INVALID;
}
break;
}
if(CompressionFormat != GMM_UNIFIED_COMP_FORMAT_INVALID)
{
//drop MC-identify bit (ie bit 5)
CompressionFormat -= (GMM_UNIFIED_COMP_MIN_MC_FORMAT - 1);
}
}
}
}
//Assert if out of MC/RC encoding range -ie format-table must be corrected for Compression code
__GMM_ASSERT(!pGmmLibContext->GetSkuTable().FtrUnified3DMediaCompressionFormats && CompressionFormat != GMM_FLATCCS_FORMAT_INVALID ||
pGmmLibContext->GetSkuTable().FtrUnified3DMediaCompressionFormats && CompressionFormat != GMM_UNIFIED_COMP_FORMAT_INVALID);
}
return CompressionFormat;
}

View File

@ -0,0 +1,437 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates This function will initialize the necessary info based on platform.
/// - Buffer type restrictions (Eg: Z, Color, Display)
/// - X/Y tile dimensions
///
/// @param[in] Platform: Contains information about platform to initialize an object
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::PlatformInfoGen8::PlatformInfoGen8(PLATFORM &Platform, Context *pGmmLibContext)
: PlatformInfo(Platform, pGmmLibContext)
{
__GMM_ASSERTPTR(pGmmLibContext, VOIDRETURN);
// --------------------------
// Non Native Dispay Interface buffer restriction. Register Ref: DSPACNTR, DSPASTRIDE, DSPASURF
// Clamping res based on 2 Nndi buffers and GMM_NNDI_SEGMENT_SIZE reserved gfx memory
// --------------------------
Data.Nndi.Alignment = PAGE_SIZE;
Data.Nndi.PitchAlignment = GMM_BYTES(1);
Data.Nndi.RenderPitchAlignment = GMM_BYTES(1);
Data.Nndi.LockPitchAlignment = GMM_BYTES(1);
Data.Nndi.MinPitch = GMM_BYTES(640);
Data.Nndi.MaxPitch = GMM_BYTES(8192);
Data.Nndi.MinAllocationSize = PAGE_SIZE;
Data.Nndi.MinHeight = GMM_SCANLINES(200);
Data.Nndi.MinWidth = GMM_PIXELS(320);
Data.Nndi.MinDepth = 0;
Data.Nndi.MaxHeight = GMM_BYTES(1536);
Data.Nndi.MaxWidth = GMM_BYTES(2048);
Data.Nndi.MaxDepth = 1;
Data.Nndi.MaxArraySize = 1;
// --------------------------
// Depth Buffer Restriction. Inst Ref: 3DSTATE_DEPTH_BUFFER
// --------------------------
Data.Depth.Alignment = PAGE_SIZE;
Data.Depth.PitchAlignment = GMM_BYTES(64);
Data.Depth.RenderPitchAlignment = GMM_BYTES(64);
Data.Depth.LockPitchAlignment = GMM_BYTES(64);
Data.Depth.MinPitch = GMM_BYTES(64);
Data.Depth.MaxPitch = GMM_KBYTE(128); // 3DSTATE_DEPTH_BUFFER has conflicting info--but 128KB should be fine.
Data.Depth.MinAllocationSize = PAGE_SIZE;
Data.Depth.MinHeight = GMM_SCANLINES(1);
Data.Depth.MinWidth = GMM_PIXELS(1);
Data.Depth.MinDepth = 0;
Data.Depth.MaxHeight = GMM_KBYTE(16);
Data.Depth.MaxWidth = GMM_KBYTE(16);
Data.Depth.MaxDepth = GMM_KBYTE(2);
Data.Depth.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Stencil Buffer Restriction. Inst Ref: 3DSTATE_STENCIL_BUFFER
// --------------------------
Data.Stencil.Alignment = PAGE_SIZE;
Data.Stencil.PitchAlignment = GMM_BYTES(128);
Data.Stencil.RenderPitchAlignment = GMM_BYTES(128);
Data.Stencil.LockPitchAlignment = GMM_BYTES(128);
Data.Stencil.MinPitch = GMM_BYTES(128);
Data.Stencil.MaxPitch = GMM_KBYTE(128); // 3DSTATE_STENCIL_BUFFER: 2*Pitch <= 128KB (GMM client allocs 2x-width, so GMM limits to that.)
Data.Stencil.MinAllocationSize = PAGE_SIZE;
Data.Stencil.MinHeight = GMM_SCANLINES(1);
Data.Stencil.MinWidth = GMM_PIXELS(1);
Data.Stencil.MinDepth = 0;
Data.Stencil.MaxHeight = GMM_KBYTE(16);
Data.Stencil.MaxWidth = GMM_KBYTE(16);
Data.Stencil.MaxDepth = GMM_KBYTE(2);
Data.Stencil.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Hierarchical Depth Buffer Restriction. Inst Ref: 3DSTATE_HIER_DEPTH_BUFFER
// --------------------------
Data.HiZ.Alignment = PAGE_SIZE;
Data.HiZ.PitchAlignment = GMM_BYTES(128);
Data.HiZ.RenderPitchAlignment = GMM_BYTES(128);
Data.HiZ.LockPitchAlignment = GMM_BYTES(128);
Data.HiZ.MinPitch = GMM_BYTES(128);
Data.HiZ.MaxPitch = GMM_KBYTE(128);
Data.HiZ.MinAllocationSize = PAGE_SIZE;
Data.HiZ.MinHeight = GMM_SCANLINES(1);
Data.HiZ.MinWidth = GMM_PIXELS(1);
Data.HiZ.MinDepth = 0;
Data.HiZ.MaxHeight = GMM_KBYTE(16);
Data.HiZ.MaxWidth = GMM_KBYTE(16);
Data.HiZ.MaxDepth = GMM_KBYTE(2);
Data.HiZ.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Vertex Restriction. Inst Ref: 3DSTATE_VERTEX_BUFFER, 3DSTATE_INSTANCE_STEP_RATE
// Note: restrictions are expanded here for UMD flexibility.
// --------------------------
Data.Vertex.Alignment = PAGE_SIZE;
Data.Vertex.PitchAlignment = GMM_BYTES(1);
Data.Vertex.LockPitchAlignment = GMM_BYTES(1);
Data.Vertex.RenderPitchAlignment = GMM_BYTES(1);
Data.Vertex.MinPitch = GMM_BYTES(1);
Data.Vertex.MaxPitch = GMM_GBYTE(2);
Data.Vertex.MinAllocationSize = PAGE_SIZE;
Data.Vertex.MinHeight = GMM_SCANLINES(1);
Data.Vertex.MinWidth = GMM_PIXELS(1);
Data.Vertex.MinDepth = 0;
Data.Vertex.MaxHeight = GMM_MBYTE(128); //TODO(Minor): How does Media fail when we change this to 1?!
Data.Vertex.MaxWidth = GMM_GBYTE(2);
Data.Vertex.MaxDepth = GMM_KBYTE(2);
Data.Vertex.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Index Buffer Restriction. Inst Ref: 3DSTATE_INDEX_BUFFER
// --------------------------
Data.Index = Data.Vertex;
// --------------------------
// Linear Buffer Restriction. General purpose. Flexible.
// --------------------------
Data.Linear.Alignment = PAGE_SIZE;
Data.Linear.PitchAlignment = GMM_BYTES(1);
Data.Linear.LockPitchAlignment = GMM_BYTES(1);
Data.Linear.RenderPitchAlignment = GMM_BYTES(1);
Data.Linear.MinPitch = GMM_BYTES(1);
Data.Linear.MaxPitch = GMM_GBYTE(2);
Data.Linear.MinAllocationSize = PAGE_SIZE;
Data.Linear.MinHeight = GMM_SCANLINES(1);
Data.Linear.MinWidth = GMM_PIXELS(1);
Data.Linear.MinDepth = 0;
Data.Linear.MaxHeight = 1;
Data.Linear.MaxWidth = GMM_GBYTE(2);
Data.Linear.MaxDepth = 1;
Data.Linear.MaxArraySize = 1;
// --------------------------
// No Surface Restriction. General purpose. Flexible.
// --------------------------
Data.NoRestriction.Alignment = PAGE_SIZE;
Data.NoRestriction.PitchAlignment = GMM_BYTES(1);
Data.NoRestriction.LockPitchAlignment = GMM_BYTES(1);
Data.NoRestriction.RenderPitchAlignment = GMM_BYTES(1);
Data.NoRestriction.MinPitch = GMM_BYTES(1);
Data.NoRestriction.MinAllocationSize = PAGE_SIZE;
Data.NoRestriction.MinHeight = GMM_SCANLINES(1);
Data.NoRestriction.MinWidth = GMM_PIXELS(1);
Data.NoRestriction.MinDepth = 0;
Data.NoRestriction.MaxHeight = GMM_GBYTE(2);
Data.NoRestriction.MaxWidth = GMM_GBYTE(256);
Data.NoRestriction.MaxPitch = GMM_GBYTE(256);
Data.NoRestriction.MaxDepth = GMM_KBYTE(2);
Data.NoRestriction.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Constant Buffer Restriction.
// --------------------------
Data.Constant = Data.NoRestriction;
// --------------------------
// Dx9 Constant Buffer pool Restriction. Inst Ref: 3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC
// --------------------------
Data.StateDx9ConstantBuffer = Data.NoRestriction;
Data.StateDx9ConstantBuffer.Alignment = GMM_KBYTE(8);
// --------------------------
// MC Buffer Restriction
// --------------------------
Data.MotionComp = Data.NoRestriction;
Data.MotionComp.Alignment = PAGE_SIZE;
Data.MotionComp.PitchAlignment = GMM_BYTES(32);
Data.MotionComp.LockPitchAlignment = GMM_BYTES(32);
Data.MotionComp.RenderPitchAlignment = GMM_BYTES(32);
Data.MotionComp.MinPitch = GMM_BYTES(32);
// --------------------------
// Stream Buffer Restriction
// --------------------------
Data.Stream = Data.NoRestriction;
// --------------------------
// Interlace Scan Buffer Restriction
// --------------------------
Data.InterlacedScan = Data.NoRestriction;
// --------------------------
// Text API Buffer Restriction
// --------------------------
Data.TextApi = Data.NoRestriction;
// --------------------------
// Overlay Buffer Restriction. Register Ref: OVADD, OSTRIDE
// --------------------------
Data.Overlay.Alignment = PAGE_SIZE;
Data.Overlay.PitchAlignment = GMM_BYTES(512);
Data.Overlay.RenderPitchAlignment = GMM_BYTES(512);
Data.Overlay.LockPitchAlignment = GMM_BYTES(512);
Data.Overlay.MinPitch = GMM_BYTES(512);
Data.Overlay.MaxPitch = GMM_KBYTE(16);
Data.Overlay.MinAllocationSize = PAGE_SIZE;
Data.Overlay.MinHeight = GMM_SCANLINES(1);
Data.Overlay.MinWidth = GMM_PIXELS(1);
Data.Overlay.MinDepth = 0;
Data.Overlay.MaxHeight = GMM_SCANLINES(4096);
Data.Overlay.MaxWidth = GMM_PIXELS(4096);
Data.Overlay.MaxDepth = 1;
Data.Overlay.MaxArraySize = 1;
// --------------------------
// RT & Texture2DSurface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.Texture2DSurface.Alignment = PAGE_SIZE;
Data.Texture2DSurface.PitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.LockPitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.MinPitch = GMM_BYTES(32);
Data.Texture2DSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.Texture2DSurface.MinAllocationSize = PAGE_SIZE;
Data.Texture2DSurface.MinHeight = GMM_SCANLINES(1);
Data.Texture2DSurface.MinWidth = GMM_PIXELS(1);
Data.Texture2DSurface.MinDepth = 0;
Data.Texture2DSurface.MaxHeight = GMM_KBYTE(16);
Data.Texture2DSurface.MaxWidth = GMM_KBYTE(16);
Data.Texture2DSurface.MaxDepth = GMM_FIELD_NA;
Data.Texture2DSurface.MaxArraySize = GMM_KBYTE(2);
{
// Linear surfaces accessed with Media Block Read/Write commands
// require 64-byte-aligned pitch. Such commands only operate on 2D
// resources, so we'll handle the requirement here. Though requirement
// applies to linear surfaces only, our up'ing the pitch alignment to
// 64 bytes here won't affect tiled surfaces, since their pitch
// alignment is never smaller than that.
Data.Texture2DLinearSurface = Data.Texture2DSurface;
Data.Texture2DLinearSurface.PitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.PitchAlignment);
Data.Texture2DLinearSurface.LockPitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.LockPitchAlignment);
Data.Texture2DLinearSurface.RenderPitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.RenderPitchAlignment);
}
// --------------------------
// AsyncFlip Restriction. Register Ref: PRI_STRIDE, PRI_SURF, SRCSZ <-- TODO(Minor): SRCSZ correct reg for W/H req's?
// --------------------------
Data.ASyncFlipSurface.Alignment = GMM_KBYTE(256);
Data.ASyncFlipSurface.PitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.RenderPitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.LockPitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.MinPitch = GMM_BYTES(64);
Data.ASyncFlipSurface.MaxPitch = Data.Texture2DSurface.MaxPitch;
Data.ASyncFlipSurface.MinAllocationSize = PAGE_SIZE;
Data.ASyncFlipSurface.MinHeight = GMM_SCANLINES(1);
Data.ASyncFlipSurface.MinWidth = GMM_PIXELS(1);
Data.ASyncFlipSurface.MinDepth = 0;
Data.ASyncFlipSurface.MaxHeight = Data.Texture2DSurface.MaxHeight; // Beyond DE requirements-Necessary for mosaic framebuffers
Data.ASyncFlipSurface.MaxWidth = Data.Texture2DSurface.MaxWidth; // Okay since GMM isn't actual display requirement gatekeeper.
Data.ASyncFlipSurface.MaxDepth = 1;
Data.ASyncFlipSurface.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Hardware MBM Restriction.
// --------------------------
Data.HardwareMBM = Data.ASyncFlipSurface;
// --------------------------
// Video Buffer Restriction
// --------------------------
Data.Video = Data.Texture2DLinearSurface;
// --------------------------
// RT & CubeSurface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.CubeSurface.Alignment = PAGE_SIZE;
Data.CubeSurface.PitchAlignment = GMM_BYTES(32);
Data.CubeSurface.LockPitchAlignment = GMM_BYTES(32);
Data.CubeSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.CubeSurface.MinPitch = GMM_BYTES(32);
Data.CubeSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.CubeSurface.MinAllocationSize = PAGE_SIZE;
Data.CubeSurface.MinHeight = GMM_SCANLINES(1);
Data.CubeSurface.MinWidth = GMM_PIXELS(1);
Data.CubeSurface.MinDepth = 0;
Data.CubeSurface.MaxHeight = GMM_KBYTE(16);
Data.CubeSurface.MaxWidth = GMM_KBYTE(16);
Data.CubeSurface.MaxDepth = 1;
Data.CubeSurface.MaxArraySize = GMM_KBYTE(2) / 6; // MaxElements / Cubefaces
// --------------------------
// RT & 3D Surface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.Texture3DSurface.Alignment = PAGE_SIZE;
Data.Texture3DSurface.PitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.LockPitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.MinPitch = GMM_BYTES(32);
Data.Texture3DSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.Texture3DSurface.MinAllocationSize = PAGE_SIZE;
Data.Texture3DSurface.MinHeight = GMM_SCANLINES(1);
Data.Texture3DSurface.MinWidth = GMM_PIXELS(1);
Data.Texture3DSurface.MinDepth = 0;
Data.Texture3DSurface.MaxHeight = GMM_KBYTE(2);
Data.Texture3DSurface.MaxWidth = GMM_KBYTE(2);
Data.Texture3DSurface.MaxDepth = GMM_KBYTE(2);
Data.Texture3DSurface.MaxArraySize = GMM_FIELD_NA;
// --------------------------
// RT & Buffer Type restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.BufferType.Alignment = PAGE_SIZE;
Data.BufferType.PitchAlignment = GMM_BYTES(32);
Data.BufferType.LockPitchAlignment = GMM_BYTES(32);
Data.BufferType.RenderPitchAlignment = GMM_BYTES(32);
Data.BufferType.MinPitch = GMM_BYTES(32);
Data.BufferType.MaxPitch = GMM_GBYTE(2);
Data.BufferType.MinAllocationSize = PAGE_SIZE;
Data.BufferType.MinHeight = GMM_SCANLINES(0);
Data.BufferType.MinWidth = GMM_PIXELS(1);
Data.BufferType.MinDepth = 0;
Data.BufferType.MaxHeight = GMM_SCANLINES(1);
Data.BufferType.MaxWidth = GMM_GBYTE(2);
Data.BufferType.MaxDepth = GMM_FIELD_NA;
Data.BufferType.MaxArraySize = GMM_GBYTE(2);
// --------------------------
// Cursor surface restricion. Register Ref: CURACNTR, CURABASE
// --------------------------
Data.Cursor.Alignment = pGmmLibContext->GetWaTable().WaCursor16K ? GMM_KBYTE(16) : PAGE_SIZE;
Data.Cursor.PitchAlignment = 1;
Data.Cursor.LockPitchAlignment = 1;
Data.Cursor.RenderPitchAlignment = 1;
Data.Cursor.MinPitch = 1;
Data.Cursor.MaxPitch = 0xffffffff;
Data.Cursor.MinAllocationSize = 1;
Data.Cursor.MinHeight = GMM_SCANLINES(1);
Data.Cursor.MinWidth = 1;
Data.Cursor.MinDepth = 0;
Data.Cursor.MaxHeight = 0xffffffff;
Data.Cursor.MaxWidth = 0xffffffff;
Data.Cursor.MaxDepth = 0xffffffff;
Data.Cursor.MaxArraySize = 1;
//--------------------------
// Set TILE_X/Y Parameters
//--------------------------
SET_TILE_MODE_INFO(LEGACY_TILE_X, 512, 8, 1, 0, 0, 0)
SET_TILE_MODE_INFO(LEGACY_TILE_Y, 128, 32, 1, 0, 0, 0)
//--------------------------
// Fence paramaters. Register Ref: FENCE
//--------------------------
Data.NumberFenceRegisters = pGmmLibContext->GetWaTable().Wa16TileFencesOnly ? 16 : 32;
Data.FenceLowBoundShift = 12;
Data.FenceLowBoundMask = GFX_MASK(12, 31);
Data.MinFenceSize = GMM_MBYTE(1);
Data.PagingBufferPrivateDataSize = GMM_KBYTE(4);
Data.MaxLod = 14; // [0,14] --> 15 Total
Data.FBCRequiredStolenMemorySize = GMM_MBYTE(8);
// --------------------------
// Surface Alignment Units
// --------------------------
Data.TexAlign.CCS.Align.Width = 256;
Data.TexAlign.CCS.Align.Height = 128;
Data.TexAlign.CCS.MaxPitchinTiles = 512;
Data.TexAlign.Compressed.Width = 1;
Data.TexAlign.Compressed.Height = 1;
Data.TexAlign.Compressed.Depth = 1;
Data.TexAlign.Depth.Width = 4; // See usage for 16bpp HALIGN_8 special-casing.
Data.TexAlign.Depth.Height = 4;
Data.TexAlign.Depth_D16_UNORM_1x_4x_16x.Width = 8;
Data.TexAlign.Depth_D16_UNORM_1x_4x_16x.Height = Data.TexAlign.Depth.Height;
Data.TexAlign.Depth_D16_UNORM_2x_8x.Width = 8;
Data.TexAlign.Depth_D16_UNORM_2x_8x.Height = Data.TexAlign.Depth.Height;
Data.TexAlign.SeparateStencil.Width = 8;
Data.TexAlign.SeparateStencil.Height = 8;
Data.TexAlign.YUV422.Width = 4;
Data.TexAlign.YUV422.Height = 4;
Data.TexAlign.AllOther.Width = 16; // HALIGN_16 required for non-MSAA RT's for CCS Fast-Clear and...TBA
Data.TexAlign.AllOther.Height = 4; // VALIGN_4 should be sufficent.
Data.TexAlign.XAdapter.Height = D3DKMT_CROSS_ADAPTER_RESOURCE_HEIGHT_ALIGNMENT;
Data.TexAlign.XAdapter.Width = 1; //minimum should be one.
// ----------------------------------
// SURFACE_STATE YOffset Granularity
// ----------------------------------
Data.SurfaceStateYOffsetGranularity = 4;
Data.SamplerFetchGranularityHeight = 4;
Data.SamplerFetchGranularityWidth = 4;
// ----------------------------------
// Restrictions for Cross adapter resource
// ----------------------------------
Data.XAdapter.Alignment = PAGE_SIZE;
Data.XAdapter.PitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.RenderPitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.LockPitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.MinPitch = GMM_BYTES(32);
Data.XAdapter.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.XAdapter.MinAllocationSize = PAGE_SIZE;
Data.XAdapter.MinHeight = GMM_SCANLINES(1);
Data.XAdapter.MinWidth = GMM_PIXELS(1);
Data.XAdapter.MinDepth = 0;
Data.XAdapter.MaxHeight = GMM_KBYTE(16);
Data.XAdapter.MaxWidth = GMM_KBYTE(16);
Data.XAdapter.MaxDepth = GMM_FIELD_NA;
Data.XAdapter.MaxArraySize = GMM_KBYTE(2);
//---------------------------------------------
//MaxSize for any surface type
//---------------------------------------------
Data.SurfaceMaxSize = GMM_GBYTE(2);
Data.MaxGpuVirtualAddressBitsPerResource = 31;
Data.MaxSLMSize = GMM_KBYTE(384);
Data.HiZPixelsPerByte = 2;
Data.ReconMaxHeight = Data.Texture2DSurface.MaxHeight; // Reconstructed surfaces require more height and width for higher resolutions.
Data.ReconMaxWidth = Data.Texture2DSurface.MaxWidth;
}

View File

@ -0,0 +1,500 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates This function will initialize the necessary info based on platform.
/// - Buffer type restrictions (Eg: Z, Color, Display)
/// - X/Y tile dimensions
///
/// @param[in] Platform: Contains information about platform to initialize an object
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::PlatformInfoGen9::PlatformInfoGen9(PLATFORM &Platform, Context *pGmmLibContext)
: PlatformInfo(Platform, pGmmLibContext)
{
__GMM_ASSERTPTR(pGmmLibContext, VOIDRETURN);
// --------------------------
// Non Native Dispay Interface buffer restriction. Register Ref: DSPACNTR, DSPASTRIDE, DSPASURF
// Clamping res based on 2 Nndi buffers and GMM_NNDI_SEGMENT_SIZE reserved gfx memory
// --------------------------
Data.Nndi.Alignment = PAGE_SIZE;
Data.Nndi.PitchAlignment = GMM_BYTES(1);
Data.Nndi.RenderPitchAlignment = GMM_BYTES(1);
Data.Nndi.LockPitchAlignment = GMM_BYTES(1);
Data.Nndi.MinPitch = GMM_BYTES(640);
Data.Nndi.MaxPitch = GMM_BYTES(8192);
Data.Nndi.MinAllocationSize = PAGE_SIZE;
Data.Nndi.MinHeight = GMM_SCANLINES(200);
Data.Nndi.MinWidth = GMM_PIXELS(320);
Data.Nndi.MinDepth = 0;
Data.Nndi.MaxHeight = GMM_BYTES(1536);
Data.Nndi.MaxWidth = GMM_BYTES(2048);
Data.Nndi.MaxDepth = 1;
Data.Nndi.MaxArraySize = 1;
// --------------------------
// Depth Buffer Restriction. Inst Ref: 3DSTATE_DEPTH_BUFFER
// --------------------------
Data.Depth.Alignment = PAGE_SIZE;
Data.Depth.PitchAlignment = GMM_BYTES(64);
Data.Depth.RenderPitchAlignment = GMM_BYTES(64);
Data.Depth.LockPitchAlignment = GMM_BYTES(64);
Data.Depth.MinPitch = GMM_BYTES(64);
Data.Depth.MaxPitch = GMM_KBYTE(128); // 3DSTATE_DEPTH_BUFFER has conflicting info--but 128KB should be fine.
Data.Depth.MinAllocationSize = PAGE_SIZE;
Data.Depth.MinHeight = GMM_SCANLINES(1);
Data.Depth.MinWidth = GMM_PIXELS(1);
Data.Depth.MinDepth = 0;
Data.Depth.MaxHeight = GMM_KBYTE(16);
Data.Depth.MaxWidth = GMM_KBYTE(16);
Data.Depth.MaxDepth = GMM_KBYTE(2);
Data.Depth.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Stencil Buffer Restriction. Inst Ref: 3DSTATE_STENCIL_BUFFER
// --------------------------
Data.Stencil.Alignment = PAGE_SIZE;
Data.Stencil.PitchAlignment = GMM_BYTES(128);
Data.Stencil.RenderPitchAlignment = GMM_BYTES(128);
Data.Stencil.LockPitchAlignment = GMM_BYTES(128);
Data.Stencil.MinPitch = GMM_BYTES(128);
Data.Stencil.MaxPitch = GMM_KBYTE(128); // 3DSTATE_STENCIL_BUFFER: 2*Pitch <= 128KB (GMM client allocs 2x-width, so GMM limits to that.)
Data.Stencil.MinAllocationSize = PAGE_SIZE;
Data.Stencil.MinHeight = GMM_SCANLINES(1);
Data.Stencil.MinWidth = GMM_PIXELS(1);
Data.Stencil.MinDepth = 0;
Data.Stencil.MaxHeight = GMM_KBYTE(16);
Data.Stencil.MaxWidth = GMM_KBYTE(16);
Data.Stencil.MaxDepth = GMM_KBYTE(2);
Data.Stencil.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Hierarchical Depth Buffer Restriction. Inst Ref: 3DSTATE_HIER_DEPTH_BUFFER
// --------------------------
Data.HiZ.Alignment = PAGE_SIZE;
Data.HiZ.PitchAlignment = GMM_BYTES(128);
Data.HiZ.RenderPitchAlignment = GMM_BYTES(128);
Data.HiZ.LockPitchAlignment = GMM_BYTES(128);
Data.HiZ.MinPitch = GMM_BYTES(128);
Data.HiZ.MaxPitch = GMM_KBYTE(128);
Data.HiZ.MinAllocationSize = PAGE_SIZE;
Data.HiZ.MinHeight = GMM_SCANLINES(1);
Data.HiZ.MinWidth = GMM_PIXELS(1);
Data.HiZ.MinDepth = 0;
Data.HiZ.MaxHeight = GMM_KBYTE(16);
Data.HiZ.MaxWidth = GMM_KBYTE(16);
Data.HiZ.MaxDepth = GMM_KBYTE(2);
Data.HiZ.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Vertex Restriction. Inst Ref: 3DSTATE_VERTEX_BUFFER, 3DSTATE_INSTANCE_STEP_RATE
// Note: restrictions are expanded here for UMD flexibility.
// --------------------------
Data.Vertex.Alignment = PAGE_SIZE;
Data.Vertex.PitchAlignment = GMM_BYTES(1);
Data.Vertex.LockPitchAlignment = GMM_BYTES(1);
Data.Vertex.RenderPitchAlignment = GMM_BYTES(1);
Data.Vertex.MinPitch = GMM_BYTES(1);
Data.Vertex.MaxPitch = GMM_GBYTE(2);
Data.Vertex.MinAllocationSize = PAGE_SIZE;
Data.Vertex.MinHeight = GMM_SCANLINES(1);
Data.Vertex.MinWidth = GMM_PIXELS(1);
Data.Vertex.MinDepth = 0;
Data.Vertex.MaxHeight = GMM_MBYTE(128); //TODO(Minor): How does Media fail when we change this to 1?!
Data.Vertex.MaxWidth = GMM_GBYTE(2);
Data.Vertex.MaxDepth = GMM_KBYTE(2);
Data.Vertex.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Index Buffer Restriction. Inst Ref: 3DSTATE_INDEX_BUFFER
// --------------------------
Data.Index = Data.Vertex;
// --------------------------
// Linear Buffer Restriction. General purpose. Flexible.
// --------------------------
Data.Linear.Alignment = PAGE_SIZE;
Data.Linear.PitchAlignment = GMM_BYTES(1);
Data.Linear.LockPitchAlignment = GMM_BYTES(1);
Data.Linear.RenderPitchAlignment = GMM_BYTES(1);
Data.Linear.MinPitch = GMM_BYTES(1);
Data.Linear.MaxPitch = GMM_GBYTE(256);
Data.Linear.MinAllocationSize = PAGE_SIZE;
Data.Linear.MinHeight = GMM_SCANLINES(1);
Data.Linear.MinWidth = GMM_PIXELS(1);
Data.Linear.MinDepth = 0;
Data.Linear.MaxHeight = 1;
Data.Linear.MaxWidth = GMM_GBYTE(256);
Data.Linear.MaxDepth = 1;
Data.Linear.MaxArraySize = 1;
// --------------------------
// No Surface Restriction. General purpose. Flexible.
// --------------------------
Data.NoRestriction.Alignment = PAGE_SIZE;
Data.NoRestriction.PitchAlignment = GMM_BYTES(1);
Data.NoRestriction.LockPitchAlignment = GMM_BYTES(1);
Data.NoRestriction.RenderPitchAlignment = GMM_BYTES(1);
Data.NoRestriction.MinPitch = GMM_BYTES(1);
Data.NoRestriction.MaxPitch = GMM_TBYTE(128);
Data.NoRestriction.MinAllocationSize = PAGE_SIZE;
Data.NoRestriction.MinHeight = GMM_SCANLINES(1);
Data.NoRestriction.MinWidth = GMM_PIXELS(1);
Data.NoRestriction.MinDepth = 0;
Data.NoRestriction.MaxHeight = GMM_GBYTE(256);
Data.NoRestriction.MaxWidth = GMM_TBYTE(128);
Data.NoRestriction.MaxDepth = GMM_KBYTE(2);
Data.NoRestriction.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Constant Buffer Restriction.
// --------------------------
Data.Constant = Data.NoRestriction;
// --------------------------
// Dx9 Constant Buffer pool Restriction. Inst Ref: 3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC
// --------------------------
Data.StateDx9ConstantBuffer = Data.NoRestriction;
Data.StateDx9ConstantBuffer.Alignment = GMM_KBYTE(8);
// --------------------------
// MC Buffer Restriction
// --------------------------
Data.MotionComp = Data.NoRestriction;
Data.MotionComp.Alignment = PAGE_SIZE;
Data.MotionComp.PitchAlignment = GMM_BYTES(32);
Data.MotionComp.LockPitchAlignment = GMM_BYTES(32);
Data.MotionComp.RenderPitchAlignment = GMM_BYTES(32);
Data.MotionComp.MinPitch = GMM_BYTES(32);
// --------------------------
// Stream Buffer Restriction
// --------------------------
Data.Stream = Data.NoRestriction;
// --------------------------
// Interlace Scan Buffer Restriction
// --------------------------
Data.InterlacedScan = Data.NoRestriction;
// --------------------------
// Text API Buffer Restriction
// --------------------------
Data.TextApi = Data.NoRestriction;
// --------------------------
// RT & Texture2DSurface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.Texture2DSurface.Alignment = PAGE_SIZE;
Data.Texture2DSurface.PitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.LockPitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.Texture2DSurface.MinPitch = GMM_BYTES(32);
Data.Texture2DSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.Texture2DSurface.MinAllocationSize = PAGE_SIZE;
Data.Texture2DSurface.MinHeight = GMM_SCANLINES(1);
Data.Texture2DSurface.MinWidth = GMM_PIXELS(1);
Data.Texture2DSurface.MinDepth = 0;
Data.Texture2DSurface.MaxHeight = GMM_KBYTE(16);
Data.Texture2DSurface.MaxWidth = GMM_KBYTE(16);
Data.Texture2DSurface.MaxDepth = GMM_FIELD_NA;
Data.Texture2DSurface.MaxArraySize = GMM_KBYTE(2);
{
// Linear surfaces accessed with Media Block Read/Write commands
// require 64-byte-aligned pitch. Such commands only operate on 2D
// resources, so we'll handle the requirement here. Though requirement
// applies to linear surfaces only, our up'ing the pitch alignment to
// 64 bytes here won't affect tiled surfaces, since their pitch
// alignment is never smaller than that.
Data.Texture2DLinearSurface = Data.Texture2DSurface;
Data.Texture2DLinearSurface.PitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.PitchAlignment);
Data.Texture2DLinearSurface.LockPitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.LockPitchAlignment);
Data.Texture2DLinearSurface.RenderPitchAlignment = GFX_MAX(GMM_BYTES(64), Data.Texture2DSurface.RenderPitchAlignment);
}
// --------------------------
// AsyncFlip Restriction. Register Ref: PRI_STRIDE, PRI_SURF, SRCSZ <-- TODO(Minor): SRCSZ correct reg for W/H req's?
// --------------------------
Data.ASyncFlipSurface.Alignment = GMM_KBYTE(256);
Data.ASyncFlipSurface.PitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.RenderPitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.LockPitchAlignment = GMM_BYTES(64);
Data.ASyncFlipSurface.MinPitch = GMM_BYTES(64);
Data.ASyncFlipSurface.MaxPitch = Data.Texture2DSurface.MaxPitch;
Data.ASyncFlipSurface.MinAllocationSize = PAGE_SIZE;
Data.ASyncFlipSurface.MinHeight = GMM_SCANLINES(1);
Data.ASyncFlipSurface.MinWidth = GMM_PIXELS(1);
Data.ASyncFlipSurface.MinDepth = 0;
Data.ASyncFlipSurface.MaxHeight = Data.Texture2DSurface.MaxHeight; // Beyond DE requirements-Necessary for mosaic framebuffers
Data.ASyncFlipSurface.MaxWidth = Data.Texture2DSurface.MaxWidth; // Okay since GMM isn't actual display requirement gatekeeper.
Data.ASyncFlipSurface.MaxDepth = 1;
Data.ASyncFlipSurface.MaxArraySize = GMM_KBYTE(2);
// --------------------------
// Hardware MBM Restriction.
// --------------------------
Data.HardwareMBM = Data.ASyncFlipSurface;
// --------------------------
// Video Buffer Restriction
// --------------------------
Data.Video = Data.Texture2DLinearSurface;
// --------------------------
// Overlay Buffer Restriction. Overlay buffer restriction will be same as Async flip surface since SKL has universal planes.
// --------------------------
Data.Overlay = Data.ASyncFlipSurface;
// --------------------------
// RT & CubeSurface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.CubeSurface.Alignment = PAGE_SIZE;
Data.CubeSurface.PitchAlignment = GMM_BYTES(32);
Data.CubeSurface.LockPitchAlignment = GMM_BYTES(32);
Data.CubeSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.CubeSurface.MinPitch = GMM_BYTES(32);
Data.CubeSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.CubeSurface.MinAllocationSize = PAGE_SIZE;
Data.CubeSurface.MinHeight = GMM_SCANLINES(1);
Data.CubeSurface.MinWidth = GMM_PIXELS(1);
Data.CubeSurface.MinDepth = 0;
Data.CubeSurface.MaxHeight = GMM_KBYTE(16);
Data.CubeSurface.MaxWidth = GMM_KBYTE(16);
Data.CubeSurface.MaxDepth = 1;
Data.CubeSurface.MaxArraySize = GMM_KBYTE(2) / 6; // MaxElements / Cubefaces
// --------------------------
// RT & 3D Surface restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.Texture3DSurface.Alignment = PAGE_SIZE;
Data.Texture3DSurface.PitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.LockPitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.RenderPitchAlignment = GMM_BYTES(32);
Data.Texture3DSurface.MinPitch = GMM_BYTES(32);
Data.Texture3DSurface.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.Texture3DSurface.MinAllocationSize = PAGE_SIZE;
Data.Texture3DSurface.MinHeight = GMM_SCANLINES(1);
Data.Texture3DSurface.MinWidth = GMM_PIXELS(1);
Data.Texture3DSurface.MinDepth = 0;
Data.Texture3DSurface.MaxHeight = GMM_KBYTE(16);
Data.Texture3DSurface.MaxWidth = GMM_KBYTE(16);
Data.Texture3DSurface.MaxDepth = GMM_KBYTE(2);
Data.Texture3DSurface.MaxArraySize = GMM_FIELD_NA;
// --------------------------
// RT & Buffer Type restrictions. Inst Ref: SURFACE_STATE
// Greatest common restriction source comes from 8bpp RT
// --------------------------
Data.BufferType.Alignment = PAGE_SIZE;
Data.BufferType.PitchAlignment = GMM_BYTES(32);
Data.BufferType.LockPitchAlignment = GMM_BYTES(32);
Data.BufferType.RenderPitchAlignment = GMM_BYTES(32);
Data.BufferType.MinPitch = GMM_BYTES(32);
Data.BufferType.MaxPitch = GMM_GBYTE(256);
Data.BufferType.MinAllocationSize = PAGE_SIZE;
Data.BufferType.MinHeight = GMM_SCANLINES(0);
Data.BufferType.MinWidth = GMM_PIXELS(1);
Data.BufferType.MinDepth = 0;
Data.BufferType.MaxHeight = GMM_SCANLINES(1);
Data.BufferType.MaxWidth = GMM_GBYTE(256);
Data.BufferType.MaxDepth = GMM_FIELD_NA;
Data.BufferType.MaxArraySize = GMM_GBYTE(2);
// --------------------------
// Cursor surface restricion. Register Ref: CURACNTR, CURABASE
// --------------------------
Data.Cursor.Alignment = pGmmLibContext->GetWaTable().WaCursor16K ? GMM_KBYTE(16) : PAGE_SIZE;
Data.Cursor.PitchAlignment = 1;
Data.Cursor.LockPitchAlignment = 1;
Data.Cursor.RenderPitchAlignment = 1;
Data.Cursor.MinPitch = 1;
Data.Cursor.MaxPitch = 0xffffffff;
Data.Cursor.MinAllocationSize = 1;
Data.Cursor.MinHeight = GMM_SCANLINES(1);
Data.Cursor.MinWidth = 1;
Data.Cursor.MinDepth = 0;
Data.Cursor.MaxHeight = 0xffffffff;
Data.Cursor.MaxWidth = 0xffffffff;
Data.Cursor.MaxDepth = 0xffffffff;
Data.Cursor.MaxArraySize = 1;
// clang-format off
/******************************************************************************************************/
/*************************************** Width, Height, Depth, MtsWidth, MtsHeight, MtsDepth */
/******************************************************************************************************/
// Legacy TILE_X/Y
SET_TILE_MODE_INFO(LEGACY_TILE_X, 512, 8, 1, 0, 0, 0)
SET_TILE_MODE_INFO(LEGACY_TILE_Y, 128, 32, 1, 0, 0, 0)
// YS 1D
SET_TILE_MODE_INFO(TILE_YS_1D_128bpe, 4096, 1, 1, 2048, 1, 1)
SET_TILE_MODE_INFO(TILE_YS_1D_64bpe, 8192, 1, 1, 4096, 1, 1)
SET_TILE_MODE_INFO(TILE_YS_1D_32bpe, 16384, 1, 1, 8192, 1, 1)
SET_TILE_MODE_INFO(TILE_YS_1D_16bpe, 32768, 1, 1, 16384, 1, 1)
SET_TILE_MODE_INFO(TILE_YS_1D_8bpe, 65536, 1, 1, 32768, 1, 1)
// YS 2D
SET_TILE_MODE_INFO(TILE_YS_2D_128bpe, 1024, 64, 1, 32, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_64bpe, 1024, 64, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_32bpe, 512, 128, 1, 64, 128, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16bpe, 512, 128, 1, 128, 128, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8bpe, 256, 256, 1, 128, 256, 1)
// YS 2D 2X
SET_TILE_MODE_INFO(TILE_YS_2D_2X_128bpe, 512, 64, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_2X_64bpe, 512, 64, 1, 64, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_2X_32bpe, 256, 128, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_2X_16bpe, 256, 128, 1, 128, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_2X_8bpe, 128, 256, 1, 128, 128, 1)
// YS 2D 4X
SET_TILE_MODE_INFO(TILE_YS_2D_4X_128bpe, 512, 32, 1, 16, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_4X_64bpe, 512, 32, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_4X_32bpe, 256, 64, 1, 32, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_4X_16bpe, 256, 64, 1, 64, 64, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_4X_8bpe, 128, 128, 1, 64, 128, 1)
// YS 2D 8X
SET_TILE_MODE_INFO(TILE_YS_2D_8X_128bpe, 256, 32, 1, 16, 16, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8X_64bpe, 256, 32, 1, 32, 16, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8X_32bpe, 128, 64, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8X_16bpe, 128, 64, 1, 64, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_8X_8bpe, 64, 128, 1, 64, 64, 1)
// YS 2D 16X
SET_TILE_MODE_INFO(TILE_YS_2D_16X_128bpe, 256, 16, 1, 8, 16, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16X_64bpe, 256, 16, 1, 16, 16, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16X_32bpe, 128, 32, 1, 16, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16X_16bpe, 128, 32, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YS_2D_16X_8bpe, 64, 64, 1, 32, 64, 1)
// YS 3D
SET_TILE_MODE_INFO(TILE_YS_3D_128bpe, 256, 16, 16, 8, 16, 16)
SET_TILE_MODE_INFO(TILE_YS_3D_64bpe, 256, 16, 16, 16, 16, 16)
SET_TILE_MODE_INFO(TILE_YS_3D_32bpe, 128, 32, 16, 16, 32, 16)
SET_TILE_MODE_INFO(TILE_YS_3D_16bpe, 64, 32, 32, 16, 32, 32)
SET_TILE_MODE_INFO(TILE_YS_3D_8bpe, 64, 32, 32, 32, 32, 32)
// YF 1D
SET_TILE_MODE_INFO(TILE_YF_1D_128bpe, 256, 1, 1, 128, 1, 1)
SET_TILE_MODE_INFO(TILE_YF_1D_64bpe, 512, 1, 1, 256, 1, 1)
SET_TILE_MODE_INFO(TILE_YF_1D_32bpe, 1024, 1, 1, 512, 1, 1)
SET_TILE_MODE_INFO(TILE_YF_1D_16bpe, 2048, 1, 1, 1024, 1, 1)
SET_TILE_MODE_INFO(TILE_YF_1D_8bpe, 4096, 1, 1, 2048, 1, 1)
// YF 2D
SET_TILE_MODE_INFO(TILE_YF_2D_128bpe, 256, 16, 1, 8, 16, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_64bpe, 256, 16, 1, 16, 16, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_32bpe, 128, 32, 1, 16, 32, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_16bpe, 128, 32, 1, 32, 32, 1)
SET_TILE_MODE_INFO(TILE_YF_2D_8bpe, 64, 64, 1, 32, 64, 1)
// YF 3D
SET_TILE_MODE_INFO(TILE_YF_3D_128bpe, 64, 8, 8, 4, 4, 8)
SET_TILE_MODE_INFO(TILE_YF_3D_64bpe, 64, 8, 8, 8, 4, 8)
SET_TILE_MODE_INFO(TILE_YF_3D_32bpe, 32, 16, 8, 8, 8, 8)
SET_TILE_MODE_INFO(TILE_YF_3D_16bpe, 16, 16, 16, 8, 8, 16)
SET_TILE_MODE_INFO(TILE_YF_3D_8bpe, 16, 16, 16, 16, 8, 16)
// clang-format on
//--------------------------
// Fence paramaters. Register Ref: FENCE
//--------------------------
Data.NumberFenceRegisters = pGmmLibContext->GetWaTable().Wa16TileFencesOnly ? 16 : 32;
Data.FenceLowBoundShift = 12;
Data.FenceLowBoundMask = GFX_MASK(12, 31);
Data.MinFenceSize = GMM_MBYTE(1);
Data.PagingBufferPrivateDataSize = GMM_KBYTE(4);
Data.MaxLod = 14; // [0,14] --> 15 Total
Data.FBCRequiredStolenMemorySize = GMM_MBYTE(8);
// --------------------------
// Surface Alignment Units
// --------------------------
Data.TexAlign.CCS.Align.Width = 128;
Data.TexAlign.CCS.Align.Height = 64;
Data.TexAlign.CCS.MaxPitchinTiles = 512;
Data.TexAlign.Compressed.Width = 4; // No reason for > HALIGN_4.
Data.TexAlign.Compressed.Height = 4; // No reason for > VALIGN_4.
Data.TexAlign.Compressed.Depth = 1;
Data.TexAlign.Depth.Width = 4; // See usage for 16bpp HALIGN_8 special-casing.
Data.TexAlign.Depth.Height = 4;
Data.TexAlign.Depth_D16_UNORM_1x_4x_16x.Width = 8;
Data.TexAlign.Depth_D16_UNORM_1x_4x_16x.Height = Data.TexAlign.Depth.Height;
Data.TexAlign.Depth_D16_UNORM_2x_8x.Width = 8;
Data.TexAlign.Depth_D16_UNORM_2x_8x.Height = Data.TexAlign.Depth.Height;
Data.TexAlign.SeparateStencil.Width = 8;
Data.TexAlign.SeparateStencil.Height = 8;
Data.TexAlign.YUV422.Width = 4;
Data.TexAlign.YUV422.Height = 4;
Data.TexAlign.AllOther.Width = 16; // HALIGN_16 required for non-MSAA RT's for CCS Fast-Clear and...TBA
Data.TexAlign.AllOther.Height = 4; // VALIGN_4 should be sufficent.
Data.TexAlign.XAdapter.Height = D3DKMT_CROSS_ADAPTER_RESOURCE_HEIGHT_ALIGNMENT;
Data.TexAlign.XAdapter.Width = 1; //minimum should be one.
// ----------------------------------
// SURFACE_STATE YOffset Granularity
// ----------------------------------
Data.SurfaceStateYOffsetGranularity = 4;
Data.SamplerFetchGranularityHeight = 4;
Data.SamplerFetchGranularityWidth = 4;
// ----------------------------------
// Restrictions for Cross adapter resource
// ----------------------------------
Data.XAdapter.Alignment = GMM_KBYTE(64); //64KB for DX12/StdSwizzle--Not worth special-casing.
Data.XAdapter.PitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.RenderPitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.LockPitchAlignment = GMM_BYTES(D3DKMT_CROSS_ADAPTER_RESOURCE_PITCH_ALIGNMENT);
Data.XAdapter.MinPitch = GMM_BYTES(32);
Data.XAdapter.MaxPitch = (pGmmLibContext->GetWaTable().WaRestrictPitch128KB) ? GMM_KBYTE(128) : GMM_KBYTE(256);
Data.XAdapter.MinAllocationSize = PAGE_SIZE;
Data.XAdapter.MinHeight = GMM_SCANLINES(1);
Data.XAdapter.MinWidth = GMM_PIXELS(1);
Data.XAdapter.MinDepth = 0;
Data.XAdapter.MaxHeight = GMM_KBYTE(16);
Data.XAdapter.MaxWidth = GMM_KBYTE(16);
Data.XAdapter.MaxDepth = GMM_FIELD_NA;
Data.XAdapter.MaxArraySize = GMM_KBYTE(2);
//---------------------------------------------
//MaxSize for any surface type
//---------------------------------------------
Data.SurfaceMaxSize = GMM_GBYTE(256);
Data.MaxGpuVirtualAddressBitsPerResource = 38;
if(GFX_IS_PRODUCT(Data.Platform, IGFX_KABYLAKE) ||
GFX_IS_PRODUCT(Data.Platform, IGFX_COFFEELAKE))
{
Data.MaxSLMSize = GMM_KBYTE(960);
}
else
{
Data.MaxSLMSize = GMM_KBYTE(576);
}
Data.HiZPixelsPerByte = 2;
Data.ReconMaxHeight = Data.Texture2DSurface.MaxHeight; // Reconstructed surfaces require more height and width for higher resolutions.
Data.ReconMaxWidth = Data.Texture2DSurface.MaxWidth;
Data.NoOfBitsSupported = 39;
Data.HighestAcceptablePhysicalAddress = GFX_MASK_LARGE(0, 38);
}

View File

@ -0,0 +1,213 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
GmmLib::PlatformInfo::PlatformInfo(PLATFORM &Platform, Context *pGmmLibContext)
{
GMM_DPF_ENTER;
memset(&Data, 0, sizeof(Data));
Data.Platform = Platform;
this->pGmmLibContext = pGmmLibContext;
GMM_RESOURCE_FORMAT GmmFormat;
#define GMM_FORMAT_GEN(X) (GFX_GET_CURRENT_RENDERCORE(Data.Platform) >= IGFX_GEN##X##_CORE)
#define GMM_FORMAT_SKU(FtrXxx) (pGmmLibContext->GetSkuTable().FtrXxx != 0)
#define GMM_FORMAT_WA(WaXxx) (pGmmLibContext->GetWaTable().WaXxx != 0)
#define GMM_COMPR_FORMAT_INVALID GMM_E2ECOMP_FORMAT_INVALID
#define GMM_FORMAT(Name, bpe, _Width, _Height, _Depth, IsRT, IsASTC, RcsSurfaceFormat, SSCompressionFmt, Availability) \
\
{ \
GmmFormat = GMM_FORMAT_##Name; \
Data.FormatTable[GmmFormat].ASTC = (IsASTC); \
Data.FormatTable[GmmFormat].Element.BitsPer = (bpe); \
Data.FormatTable[GmmFormat].Element.Depth = (_Depth); \
Data.FormatTable[GmmFormat].Element.Height = (_Height); \
Data.FormatTable[GmmFormat].Element.Width = (_Width); \
Data.FormatTable[GmmFormat].RenderTarget = ((IsRT) != 0); \
Data.FormatTable[GmmFormat].SurfaceStateFormat = ((GMM_SURFACESTATE_FORMAT)(RcsSurfaceFormat)); \
Data.FormatTable[GmmFormat].CompressionFormat.CompressionFormat = (SSCompressionFmt); \
Data.FormatTable[GmmFormat].Supported = ((Availability) != 0); \
if(((_Depth) > 1) || ((_Height) > 1) || ((_Width) > 1)) \
{ \
Data.FormatTable[GmmFormat].Compressed = 1; \
} \
}
#include "External/Common/GmmFormatTable.h"
}
/////////////////////////////////////////////////////////////////////////////////////
/// Copies parameters or sets flags based on info sent by the client.
///
/// @param[in] CreateParams: Flags which specify what sort of resource to create
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::PlatformInfo::SetCCSFlag(GMM_RESOURCE_FLAG &Flags)
{
if(Flags.Gpu.MCS)
{
Flags.Gpu.CCS = Flags.Gpu.MCS;
}
Flags.Info.RenderCompressed = Flags.Info.MediaCompressed = 0;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Validates the MMC parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @param[in] GMM_TEXTURE_INFO which specify what sort of resource to create
/// @return 1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::PlatformInfo::ValidateMMC(GMM_TEXTURE_INFO &Surf)
{
if(Surf.Flags.Gpu.MMC && //For Media Memory Compression --
((!(GMM_IS_4KB_TILE(Surf.Flags) || GMM_IS_64KB_TILE(Surf.Flags))) ||
Surf.ArraySize > GMM_MAX_MMC_INDEX))
{
return 0;
}
return 1;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Validates the parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @param[in] GMM_TEXTURE_INFO which specify what sort of resource to create
/// @return 1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::PlatformInfo::ValidateCCS(GMM_TEXTURE_INFO &Surf)
{
if(!( //--- Legitimate CCS Case ----------------------------------------
((Surf.Type >= RESOURCE_2D && Surf.Type <= RESOURCE_BUFFER) && //Not supported: 1D; Supported: Buffer, 2D, 3D, cube, Arrays, mip-maps, MSAA, Depth/Stencil
(Surf.Type <= RESOURCE_CUBE)) ||
(Surf.Type == RESOURCE_2D && Surf.MaxLod == 0)))
{
GMM_ASSERTDPF(0, "Invalid CCS usage!");
return 0;
}
if(Surf.Flags.Info.RenderCompressed && Surf.Flags.Info.MediaCompressed)
{
GMM_ASSERTDPF(0, "Invalid CCS usage - can't be both RC and MC!");
return 0;
}
return 1;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Validates the UnifiedAuxSurface parameters passed in by clients to make sure they do not
/// conflict or ask for unsupporting combinations/features.
///
/// @param[in] GMM_TEXTURE_INFO which specify what sort of resource to create
/// @return 1 is validation passed. 0 otherwise.
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::PlatformInfo::ValidateUnifiedAuxSurface(GMM_TEXTURE_INFO &Surf)
{
if((Surf.Flags.Gpu.UnifiedAuxSurface) &&
!( //--- Legitimate UnifiedAuxSurface Case ------------------------------------------
Surf.Flags.Gpu.CCS &&
(Surf.MSAA.NumSamples <= 1 && (Surf.Flags.Gpu.RenderTarget || Surf.Flags.Gpu.Texture))))
{
GMM_ASSERTDPF(0, "Invalid UnifiedAuxSurface usage!");
return 0;
}
return 1;
}
//=============================================================================
//
// Function: CheckFmtDisplayDecompressible
//
// Desc: Returns true if display hw supports lossless render/media decompression
// else returns false.
// Umds can call it to decide if full resolve is required
//
// Parameters:
// See function arguments.
//
// Returns:
// uint8_t
//-----------------------------------------------------------------------------
uint8_t GmmLib::PlatformInfo::CheckFmtDisplayDecompressible(GMM_TEXTURE_INFO &Surf,
bool IsSupportedRGB64_16_16_16_16,
bool IsSupportedRGB32_8_8_8_8,
bool IsSupportedRGB32_2_10_10_10,
bool IsSupportedMediaFormats)
{
bool IsRenderCompressed = false;
GMM_UNREFERENCED_PARAMETER(IsSupportedMediaFormats);
GMM_UNREFERENCED_PARAMETER(IsSupportedRGB64_16_16_16_16);
GMM_UNREFERENCED_PARAMETER(Surf);
if(IsSupportedRGB32_8_8_8_8 || //RGB32 8 : 8 : 8 : 8
(GFX_GET_CURRENT_DISPLAYCORE(pGmmLibContext->GetPlatformInfo().Platform) >= IGFX_GEN10_CORE &&
IsSupportedRGB32_2_10_10_10)) //RGB32 2 : 10 : 10 : 10))
{
IsRenderCompressed = true;
}
return IsRenderCompressed;
}
/////////////////////////////////////////////////////////////////////////////////////
/// C wrapper to get platform info data pointer (non-override platform info)
///
/// @return Pointer to platform info data
/////////////////////////////////////////////////////////////////////////////////////
const GMM_PLATFORM_INFO *GMM_STDCALL __GmmGetPlatformInfo(void *pLibContext)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
__GMM_ASSERTPTR(pGmmLibContext, NULL)
if(pGmmLibContext->GetPlatformInfoObj() != NULL)
{
return (const GMM_PLATFORM_INFO *)(&(pGmmLibContext->GetPlatformInfo()));
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////////////////
/// @param[in] Number: Number of Fence Registers
/////////////////////////////////////////////////////////////////////////////////////
void GMM_STDCALL __SetNumberFenceRegisters(void *pLibContext, uint32_t Number)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
__GMM_ASSERT(pGmmLibContext != NULL)
if(pGmmLibContext != NULL && pGmmLibContext->GetPlatformInfoObj() != NULL)
{
pGmmLibContext->GetPlatformInfoObj()->SetDataNumberFenceRegisters(Number);
}
}
uint32_t GMM_STDCALL GmmPlatformGetBppFromGmmResourceFormat(void *pLibContext, GMM_RESOURCE_FORMAT Format)
{
GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
__GMM_ASSERT((Format > GMM_FORMAT_INVALID) && (Format < GMM_RESOURCE_FORMATS));
__GMM_ASSERT(pGmmLibContext);
__GMM_ASSERT(pGmmLibContext->GetPlatformInfo().FormatTable[Format].Element.BitsPer >> 3);
return pGmmLibContext->GetPlatformInfo().FormatTable[Format].Element.BitsPer;
}

View File

@ -0,0 +1,122 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#ifdef __cplusplus
#include "../inc/External/Common/GmmMemAllocator.hpp"
#include "../inc/External/Common/GmmTextureExt.h"
namespace GmmLib {
class Context;
class NON_PAGED_SECTION PlatformInfo : public GmmMemAllocator
{
public:
static int32_t RefCount;
static int32_t OverrideRefCount;
protected:
GMM_PLATFORM_INFO Data;
Context * pGmmLibContext;
public:
PlatformInfo(PLATFORM &Platform, Context* pGmmLibContext);
virtual ~PlatformInfo()
{
}
const GMM_PLATFORM_INFO& GetData()
{
return Data;
}
virtual void ApplyExtendedTexAlign(uint32_t CCSMode, ALIGNMENT& UnitAlign)
{
GMM_UNREFERENCED_PARAMETER(CCSMode);
GMM_UNREFERENCED_PARAMETER(UnitAlign);
}
virtual uint8_t OverrideCompressionFormat(GMM_RESOURCE_FORMAT Format, uint8_t IsMC)
{
GMM_UNREFERENCED_PARAMETER(Format);
GMM_UNREFERENCED_PARAMETER(IsMC);
return 0;
}
void SetDataSurfaceMaxSize(uint64_t Size)
{
Data.SurfaceMaxSize = Size;
}
void SetDataFBCRequiredStolenMemorySize(uint32_t Size)
{
Data.FBCRequiredStolenMemorySize = Size;
}
void SetDataNumberFenceRegisters(uint32_t Number)
{
Data.NumberFenceRegisters = Number;
}
virtual void SetCCSFlag(GMM_RESOURCE_FLAG &Flags);
virtual uint8_t ValidateMMC(GMM_TEXTURE_INFO &Surf);
virtual uint8_t ValidateCCS(GMM_TEXTURE_INFO &Surf);
virtual uint8_t ValidateUnifiedAuxSurface(GMM_TEXTURE_INFO &Surf);
virtual uint8_t CheckFmtDisplayDecompressible(GMM_TEXTURE_INFO &Surf,
bool IsSupportedRGB64_16_16_16_16,
bool IsSupportedRGB32_8_8_8_8,
bool IsSupportedRGB32_2_10_10_10,
bool IsSupportedMediaFormats);
};
}
#define GMM_PLATFORM_INFO_CLASS GmmLib::PlatformInfo
#else
typedef struct PlatformInfo PlatformInfo;
#define GMM_PLATFORM_INFO_CLASS PlatformInfo
#endif
//***************************************************************************
//
// GMM_PLATFORM_INFO Internl API
//
//***************************************************************************
#define SET_TILE_MODE_INFO(Mode, _Width, _Height, _Depth, _MtsWidth, _MtsHeight, _MtsDepth) \
{ \
Data.TileInfo[Mode].LogicalTileWidth = GMM_BYTES(_Width); \
Data.TileInfo[Mode].LogicalTileHeight = GMM_SCANLINES(_Height); \
Data.TileInfo[Mode].LogicalTileDepth = (_Depth); \
Data.TileInfo[Mode].LogicalSize = (_Width) * (_Height) * (_Depth); \
Data.TileInfo[Mode].MaxPitch = GMM_KBYTE(256); \
Data.TileInfo[Mode].MaxMipTailStartWidth = (_MtsWidth); \
Data.TileInfo[Mode].MaxMipTailStartHeight = (_MtsHeight); \
Data.TileInfo[Mode].MaxMipTailStartDepth = (_MtsDepth); \
}
#if __cplusplus
extern "C" {
#endif
const GMM_PLATFORM_INFO *GMM_STDCALL __GmmGetPlatformInfo(void *pLibContext);
void GMM_STDCALL __SetNumberFenceRegisters(void *pLibContext, uint32_t Number);
#if __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,838 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// Checks that clients only set Presentable flag during a resource allocation, ONLY
/// when a platform supported render target is selected in ::GMM_RESOURCE_FORMAT enum.
///
/// @return true if displayable, false otherwise.
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::GmmResourceInfoCommon::IsPresentableformat()
{
const GMM_PLATFORM_INFO *pPlatform;
const GMM_FORMAT_ENTRY * FormatTable = NULL;
GMM_DPF_ENTER;
__GMM_ASSERTPTR(GetGmmLibContext(), false);
pPlatform = GMM_OVERRIDE_PLATFORM_INFO(&Surf, GetGmmLibContext());
FormatTable = &(pPlatform->FormatTable[0]);
if(Surf.Flags.Gpu.Presentable == false)
{
// When Presentable flag is not set, no reason to check for valid RT
// platform supported format. Safe to return true.
return true;
}
if((Surf.Format > GMM_FORMAT_INVALID) &&
(Surf.Format < GMM_RESOURCE_FORMATS))
{
if((FormatTable[Surf.Format].RenderTarget) &&
(FormatTable[Surf.Format].Supported))
{
return true;
}
else
{
GMM_ASSERTDPF(0, "Present flag can only be set w/ a format!");
return false;
}
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the restrictions that a particular resource must follow on a particular
/// OS or hardware.
///
/// @param[out] Restrictions: restrictions that this resource must adhere to
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmResourceInfoCommon::GetRestrictions(__GMM_BUFFER_TYPE &Restrictions)
{
GMM_DPF_ENTER;
GMM_TEXTURE_CALC *pTextureCalc = NULL;
pTextureCalc = GMM_OVERRIDE_TEXTURE_CALC(&Surf, GetGmmLibContext());
pTextureCalc->GetResRestrictions(&Surf, Restrictions);
GMM_DPF_EXIT;
}
//=============================================================================
//
// Function: GmmResGetRestrictions
//
// Desc: This routine returns resource restrictions
//
// Parameters:
// pPlatform: ptr to HW_DEVICE_EXTENSION
// pResourceInfo: ptr to GMM_RESOURCE_INFO
// pRestrictions: ptr to restrictions
//
// Returns:
// void
//
//-----------------------------------------------------------------------------
void GMM_STDCALL GmmResGetRestrictions(GMM_RESOURCE_INFO *pResourceInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
pResourceInfo->GetRestrictions(*pRestrictions);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the best restrictions by comparing two buffer types. Each buffer type
/// carries alignment and size restrictions.
///
/// @param[in] pFirstBuffer: Contains surface alignment and size restrictions
/// @param[in] pSecondBuffer: Contains surface alignment and size restrictions
///
/// @return Best Restrictions based on the two parameters passed
/////////////////////////////////////////////////////////////////////////////////////
__GMM_BUFFER_TYPE *GmmLib::GmmTextureCalc::GetBestRestrictions(__GMM_BUFFER_TYPE * pFirstBuffer,
const __GMM_BUFFER_TYPE *pSecondBuffer)
{
GMM_DPF_ENTER;
if(IsRestrictionInvalid(pFirstBuffer)) //default
{
*pFirstBuffer = *pSecondBuffer;
return pFirstBuffer;
}
pFirstBuffer->Alignment = GFX_MAX(pFirstBuffer->Alignment,
pSecondBuffer->Alignment);
pFirstBuffer->PitchAlignment = GFX_MAX(pFirstBuffer->PitchAlignment,
pSecondBuffer->PitchAlignment);
pFirstBuffer->RenderPitchAlignment = GFX_MAX(pFirstBuffer->RenderPitchAlignment,
pSecondBuffer->RenderPitchAlignment);
pFirstBuffer->LockPitchAlignment = GFX_MAX(pFirstBuffer->LockPitchAlignment,
pSecondBuffer->LockPitchAlignment);
pFirstBuffer->MinPitch = GFX_MAX(pFirstBuffer->MinPitch,
pSecondBuffer->MinPitch);
pFirstBuffer->MinAllocationSize = GFX_MAX(pFirstBuffer->MinAllocationSize,
pSecondBuffer->MinAllocationSize);
pFirstBuffer->MinDepth = GFX_MAX(pFirstBuffer->MinDepth,
pSecondBuffer->MinDepth);
pFirstBuffer->MinHeight = GFX_MAX(pFirstBuffer->MinHeight,
pSecondBuffer->MinHeight);
pFirstBuffer->MinWidth = GFX_MAX(pFirstBuffer->MinWidth,
pSecondBuffer->MinWidth);
pFirstBuffer->MaxDepth = GFX_MIN(pFirstBuffer->MaxDepth,
pSecondBuffer->MaxDepth);
pFirstBuffer->MaxHeight = GFX_MIN(pFirstBuffer->MaxHeight,
pSecondBuffer->MaxHeight);
pFirstBuffer->MaxWidth = GFX_MIN(pFirstBuffer->MaxWidth,
pSecondBuffer->MaxWidth);
pFirstBuffer->NeedPow2LockAlignment = pFirstBuffer->NeedPow2LockAlignment |
pSecondBuffer->NeedPow2LockAlignment;
GMM_DPF_EXIT;
return pFirstBuffer;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns restrictions for 1D, 2D, 3D textures depending on how the surface
/// may possibliy be used.
///
/// @param[out] pBuff: Restrictions filled in this struct
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmTextureCalc::GetGenericRestrictions(GMM_TEXTURE_INFO *pTexInfo, __GMM_BUFFER_TYPE *pBuff)
{
GMM_DPF_ENTER;
const GMM_PLATFORM_INFO *pPlatformResource = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
if(pTexInfo->Flags.Gpu.NoRestriction)
{
// Impose zero restrictions. Ignore any other GPU usage flags
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->NoRestriction);
return;
}
if(pTexInfo->Flags.Gpu.Texture)
{
if(pTexInfo->Type == RESOURCE_BUFFER)
{
*pBuff = pPlatformResource->BufferType;
}
else if(pTexInfo->Type == RESOURCE_CUBE)
{
*pBuff = pPlatformResource->CubeSurface;
}
else if(pTexInfo->Type == RESOURCE_3D)
{
*pBuff = pPlatformResource->Texture3DSurface;
}
else
{
*pBuff = pPlatformResource->Texture2DSurface;
if(pTexInfo->Flags.Info.Linear)
{
*pBuff = pPlatformResource->Texture2DLinearSurface;
}
if(GmmIsReconstructableSurface(pTexInfo->Format))
{
pBuff->MaxHeight = pPlatformResource->ReconMaxHeight;
pBuff->MaxWidth = pPlatformResource->ReconMaxWidth;
}
}
}
if(pTexInfo->Flags.Gpu.RenderTarget ||
pTexInfo->Flags.Gpu.CCS ||
pTexInfo->Flags.Gpu.MCS)
{
// Gen7 onwards, bound by SURFACE_STATE constraints.
if(pTexInfo->Type == RESOURCE_BUFFER)
{
*pBuff = pPlatformResource->BufferType;
}
else if(pTexInfo->Type == RESOURCE_CUBE)
{
*pBuff = pPlatformResource->CubeSurface;
}
else if(pTexInfo->Type == RESOURCE_3D)
{
*pBuff = pPlatformResource->Texture3DSurface;
}
else
{
*pBuff = pPlatformResource->Texture2DSurface;
if(pTexInfo->Flags.Info.Linear)
{
*pBuff = pPlatformResource->Texture2DLinearSurface;
}
if(GmmIsReconstructableSurface(pTexInfo->Format))
{
pBuff->MaxHeight = pPlatformResource->ReconMaxHeight;
pBuff->MaxWidth = pPlatformResource->ReconMaxWidth;
}
}
}
if(pTexInfo->Flags.Gpu.Depth)
{
// Z
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Depth);
}
if(pTexInfo->Flags.Gpu.Vertex)
{
// VertexData
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Vertex);
}
if(pTexInfo->Flags.Gpu.Index)
{
// Index buffer
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Index);
}
if(pTexInfo->Flags.Gpu.FlipChain)
{
// Async Flip
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->ASyncFlipSurface);
}
if(pTexInfo->Flags.Gpu.MotionComp)
{
// Media buffer
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->MotionComp);
}
if(pTexInfo->Flags.Gpu.State ||
pTexInfo->Flags.Gpu.InstructionFlat ||
pTexInfo->Flags.Gpu.ScratchFlat)
{
// indirect state
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Vertex);
}
if(pTexInfo->Flags.Gpu.Query ||
pTexInfo->Flags.Gpu.HistoryBuffer)
{
// Query
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->NoRestriction);
}
if(pTexInfo->Flags.Gpu.Constant)
{
//
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Constant);
}
if(pTexInfo->Flags.Gpu.Stream)
{
//
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Stream);
}
if(pTexInfo->Flags.Gpu.InterlacedScan)
{
//
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->InterlacedScan);
}
if(pTexInfo->Flags.Gpu.TextApi)
{
//
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->TextApi);
}
if(pTexInfo->Flags.Gpu.SeparateStencil)
{
//
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Stencil);
}
if(pTexInfo->Flags.Gpu.HiZ)
{
//
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->HiZ);
}
if(pTexInfo->Flags.Gpu.Video)
{
//
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Video);
if(GmmIsReconstructableSurface(pTexInfo->Format))
{
pBuff->MaxHeight = pPlatformResource->ReconMaxHeight;
pBuff->MaxWidth = pPlatformResource->ReconMaxWidth;
}
}
if(pTexInfo->Flags.Gpu.StateDx9ConstantBuffer)
{
//
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->StateDx9ConstantBuffer);
}
if(pTexInfo->Flags.Gpu.Overlay)
{
// Overlay buffer use Async Flip values
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->Overlay);
if((pTexInfo->Format == GMM_FORMAT_YUY2) && (pTexInfo->BaseWidth == 640))
{
// override the pitch alignment
pBuff->PitchAlignment = 64;
}
}
if(pTexInfo->Flags.Info.XAdapter)
{
//Add Cross Adapter resource restriction for hybrid graphics.
pBuff = GetBestRestrictions(pBuff, &pPlatformResource->XAdapter);
if(pTexInfo->Type == RESOURCE_BUFFER)
{
pBuff->MaxWidth = pPlatformResource->SurfaceMaxSize;
pBuff->MaxPitch = pPlatformResource->BufferType.MaxPitch;
pBuff->MaxHeight = 1;
}
}
//Non Aligned ExistingSysMem Special cases.
if((pTexInfo->Flags.Info.ExistingSysMem &&
(!pTexInfo->ExistingSysMem.IsGmmAllocated) &&
(!pTexInfo->ExistingSysMem.IsPageAligned)))
{
if(pTexInfo->Flags.Info.Linear ||
pTexInfo->Flags.Info.SVM)
{
if(pTexInfo->Type == RESOURCE_BUFFER)
{
//Use combination of BufferType, NoRestriction to support large buffer with minimal pitch alignment
*pBuff = pPlatformResource->BufferType;
pBuff->PitchAlignment = pPlatformResource->NoRestriction.PitchAlignment;
pBuff->LockPitchAlignment = pPlatformResource->NoRestriction.LockPitchAlignment;
pBuff->RenderPitchAlignment = pPlatformResource->NoRestriction.LockPitchAlignment;
pBuff->MinPitch = pPlatformResource->NoRestriction.MinPitch;
}
//[To DO] Handle other types when needed!
}
/*
else if(Surf.Flags.Gpu.Texture)
{
//Override as and when required
}
else if(Surf.Flags.Gpu.RenderTarget)
{
//Overide as and when Required
}*/
}
GMM_DPF_EXIT;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Internal function resets the restrictions and puts the allocation in invalid state
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: reset the restrictions to invalid state.
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmTextureCalc::ResetRestrictions(__GMM_BUFFER_TYPE *pRestriction)
{
pRestriction->MinDepth = 0xffffffff;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Internal function returns the best restrictions depending on how the surface may
/// possibly be used.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: Reference to surface alignment and size restrictions
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmTextureCalc::GetTexRestrictions(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
GMM_DPF_ENTER;
GetResRestrictions(pTexInfo, *pRestrictions);
GMM_DPF_EXIT;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the restrictions that a particular resource must follow on a particular
/// OS or hardware.
///
/// @param[out] Restrictions: restrictions that this resource must adhere to
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmTextureCalc::GetResRestrictions(GMM_TEXTURE_INFO * pTexinfo,
__GMM_BUFFER_TYPE &Restrictions)
{
GMM_DPF_ENTER;
const GMM_PLATFORM_INFO *pPlatform = NULL;
GMM_RESOURCE_FLAG ZeroGpuFlags;
__GMM_ASSERTPTR(pGmmLibContext, VOIDRETURN);
pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexinfo, pGmmLibContext);
// Check that at least one usage flag is set for allocations other than
// Primary/Shadow/Staging.
memset(&ZeroGpuFlags.Gpu, 0, sizeof(ZeroGpuFlags.Gpu));
if((pTexinfo->Type <= RESOURCE_KMD_CHECK_START ||
pTexinfo->Type >= RESOURCE_KMD_CHECK_END) &&
!memcmp(&pTexinfo->Flags.Gpu, &ZeroGpuFlags.Gpu, sizeof(ZeroGpuFlags.Gpu)))
{
GMM_ASSERTDPF(0, "No GPU Usage specified!");
return;
}
ResetRestrictions(&Restrictions); //Set to Default
// Get worst case restrictions that match GPU flags set in resource
switch(pTexinfo->Type)
{
case RESOURCE_1D:
case RESOURCE_2D:
case RESOURCE_3D:
case RESOURCE_CUBE:
case RESOURCE_BUFFER:
case RESOURCE_SCRATCH:
case RESOURCE_GDI:
GetGenericRestrictions(pTexinfo, &Restrictions);
break;
case RESOURCE_HW_CONTEXT:
case RESOURCE_TAG_PAGE:
if(pTexinfo->Flags.Info.TiledW ||
pTexinfo->Flags.Info.TiledX ||
GMM_IS_4KB_TILE(pTexinfo->Flags))
{
GMM_ASSERTDPF(0, "Tiled Pref specified for RESOURCE_LINEAR!");
return;
}
GetLinearRestrictions(pTexinfo, &Restrictions);
break;
case RESOURCE_PRIMARY:
case RESOURCE_SHADOW:
case RESOURCE_STAGING:
GetPrimaryRestrictions(pTexinfo, &Restrictions);
break;
case RESOURCE_NNDI:
Restrictions = pPlatform->Nndi;
break;
case RESOURCE_HARDWARE_MBM:
case RESOURCE_IFFS_MAPTOGTT:
//Hardware MBM resource request can come for overlay allocation or normal
//displayable allocation. So get the restrictions accordingly
if(pTexinfo->Flags.Gpu.Overlay)
{
Restrictions = pPlatform->Overlay;
}
else
{
Restrictions = pPlatform->HardwareMBM;
}
break;
case RESOURCE_CURSOR:
case RESOURCE_PWR_CONTEXT:
case RESOURCE_KMD_BUFFER:
case RESOURCE_NULL_CONTEXT_INDIRECT_STATE:
case RESOURCE_PERF_DATA_QUEUE:
case RESOURCE_GLOBAL_BUFFER:
case RESOURCE_FBC:
case RESOURCE_GFX_CLIENT_BUFFER:
Restrictions = pPlatform->Cursor;
break;
case RESOURCE_OVERLAY_DMA:
Restrictions = pPlatform->NoRestriction;
break;
case RESOURCE_GTT_TRANSFER_REGION:
GetGenericRestrictions(pTexinfo, &Restrictions);
break;
case RESOURCE_OVERLAY_INTERMEDIATE_SURFACE:
Restrictions = pPlatform->Overlay;
break;
default:
GetGenericRestrictions(pTexinfo, &Restrictions);
GMM_ASSERTDPF(0, "Unkown Resource type");
}
// Apply any specific WA
if(((pTexinfo->Flags.Wa.ILKNeedAvcMprRowStore32KAlign)) ||
((pTexinfo->Flags.Wa.ILKNeedAvcDmvBuffer32KAlign)))
{
Restrictions.Alignment = GFX_ALIGN(Restrictions.Alignment, GMM_KBYTE(32));
}
if(pGmmLibContext->GetWaTable().WaAlignContextImage && (pTexinfo->Type == RESOURCE_HW_CONTEXT))
{
Restrictions.Alignment = GFX_ALIGN(Restrictions.Alignment, GMM_KBYTE(64));
}
if(pTexinfo->Flags.Gpu.S3d &&
pTexinfo->Flags.Info.Linear &&
!pGmmLibContext->GetSkuTable().FtrDisplayEngineS3d)
{
Restrictions.Alignment = PAGE_SIZE;
Restrictions.PitchAlignment = PAGE_SIZE;
}
if(pTexinfo->Flags.Gpu.TiledResource)
{
// Need at least 64KB alignment to track tile mappings (h/w or s/w tracking).
Restrictions.Alignment = GFX_ALIGN(Restrictions.Alignment, GMM_KBYTE(64));
// Buffer tiled resources are trivially divided into 64KB tiles => Pitch must divide into 64KB tiles
if(pTexinfo->Type == RESOURCE_BUFFER)
{
Restrictions.PitchAlignment = GFX_ALIGN(Restrictions.PitchAlignment, GMM_KBYTE(64));
}
if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE)
{
pGmmLibContext->GetPlatformInfo().SurfaceMaxSize = GMM_TBYTE(1);
}
}
// SKL TileY Display needs 1MB alignment.
if(((pTexinfo->Type == RESOURCE_PRIMARY) ||
pTexinfo->Flags.Gpu.FlipChain) &&
(GMM_IS_4KB_TILE(pTexinfo->Flags) ||
pTexinfo->Flags.Info.TiledYf))
{
Restrictions.Alignment = GMM_MBYTE(1);
}
if(pTexinfo->Flags.Info.RenderCompressed ||
pTexinfo->Flags.Info.MediaCompressed)
{
if(pGmmLibContext->GetSkuTable().FtrFlatPhysCCS)
{
Restrictions.Alignment = GFX_ALIGN(Restrictions.Alignment, GMM_KBYTE(64));
}
else // only for platforms having auxtable
{
Restrictions.Alignment = GFX_ALIGN(Restrictions.Alignment, (!WA16K(pGmmLibContext) ? GMM_KBYTE(64) : GMM_KBYTE(16)));
}
}
GMM_DPF_EXIT;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates surface size based on Non Aligned ExistingSysMem restrictions.
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmResourceInfoCommon::ApplyExistingSysMemRestrictions()
{
const GMM_PLATFORM_INFO *pPlatform;
// Handle Minimal Restriction ExistingSysMem Requirements...
GMM_GFX_SIZE_T AdditionalPaddingBytes = 0;
GMM_GFX_SIZE_T AdditionalPaddingRows = 0;
GMM_GFX_SIZE_T BaseAlignment = 1; // 1 = Byte Alignment
GMM_GFX_SIZE_T EndAlignment = 1; // 1 = Byte Alignment
GMM_GFX_SIZE_T SizePadding = 1; // 1 = Byte Padding
uint32_t CompressHeight, CompressWidth, CompressDepth;
GMM_GFX_SIZE_T Width, Height;
GMM_TEXTURE_INFO *pTexInfo = &Surf;
GMM_TEXTURE_CALC *pTextureCalc;
GMM_DPF_ENTER;
pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, GetGmmLibContext());
pTextureCalc = GMM_OVERRIDE_TEXTURE_CALC(pTexInfo, GetGmmLibContext());
Height = pTexInfo->BaseHeight;
Width = pTexInfo->BaseWidth;
#define UPDATE_BASE_ALIGNMENT(a) \
{ \
__GMM_ASSERT((GFX_MAX(BaseAlignment, a) % GFX_MIN(BaseAlignment, a)) == 0); /* Revisit if ever have to support complex alignments. */ \
BaseAlignment = GFX_MAX(BaseAlignment, a); \
}
#define UPDATE_PADDING(p) \
{ \
SizePadding = GFX_MAX(SizePadding, p); \
}
#define UPDATE_ADDITIONAL_ROWS(r) \
{ \
AdditionalPaddingRows = GFX_MAX(AdditionalPaddingRows, r); \
}
#define UPDATE_ADDITIONAL_BYTES(b) \
{ \
AdditionalPaddingBytes = GFX_MAX(AdditionalPaddingBytes, b); \
}
#define UPDATE_END_ALIGNMENT(a) \
{ \
__GMM_ASSERT((GFX_MAX(EndAlignment, a) % GFX_MIN(EndAlignment, a)) == 0); /* Revisit if ever have to support complex alignments. */ \
EndAlignment = GFX_MAX(EndAlignment, a); \
}
if(!pTexInfo->Pitch)
{
__GMM_ASSERT(pTexInfo->Type == RESOURCE_1D); // Clients can leave pitch zero for 1D, and we'll fill-in...
pTexInfo->Pitch = Width * (pTexInfo->BitsPerPixel >> 3);
}
__GMM_ASSERT( // Currently limiting our support...
pTexInfo->Flags.Gpu.NoRestriction ||
pTexInfo->Flags.Gpu.Index ||
pTexInfo->Flags.Gpu.RenderTarget ||
pTexInfo->Flags.Gpu.Texture ||
pTexInfo->Flags.Gpu.Vertex);
__GMM_ASSERT( // Trivial, Linear Surface...
((pTexInfo->Type == RESOURCE_BUFFER) || (pTexInfo->Type == RESOURCE_1D) || (pTexInfo->Type == RESOURCE_2D)) &&
(pTexInfo->MaxLod == 0) &&
!GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]) &&
!GmmIsPlanar(pTexInfo->Format) &&
((pTexInfo->ArraySize <= 1) || (pTexInfo->Type == RESOURCE_BUFFER)));
__GMM_ASSERT( // Valid Surface...
(Width > 0) &&
!((pTexInfo->Type == RESOURCE_BUFFER) && GmmIsYUVPacked(pTexInfo->Format)));
// Convert to compression blocks, if applicable...
if(GmmIsCompressed(GetGmmLibContext(), pTexInfo->Format))
{
pTextureCalc->GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
Width = GFX_CEIL_DIV(Width, CompressWidth);
Height = GFX_CEIL_DIV(Height, CompressHeight);
}
__GMM_ASSERT( // Valid Surface Follow-Up...
(pTexInfo->Pitch >= (Width * (pTexInfo->BitsPerPixel >> 3))));
if(!pTexInfo->Flags.Gpu.NoRestriction && !pTexInfo->Flags.Info.SVM && !pTexInfo->Flags.Info.Linear)
{
if(pTexInfo->Flags.Gpu.Index) /////////////////////////////////////////////////////////
{
__GMM_ASSERT(!(
pTexInfo->Flags.Gpu.RenderTarget ||
pTexInfo->Flags.Gpu.Texture ||
pTexInfo->Flags.Gpu.Vertex)); // Can explore if needed what combo's make sense--and how req's should combine.
// 3DSTATE_INDEX_BUFFER...
UPDATE_BASE_ALIGNMENT(4); // 32-bit worst-case, since GMM doesn't receive element-size from clients.
if(GetGmmLibContext()->GetWaTable().WaAlignIndexBuffer)
{
UPDATE_END_ALIGNMENT(64);
}
else
{
UPDATE_END_ALIGNMENT(1);
}
}
if(pTexInfo->Flags.Gpu.Vertex) ////////////////////////////////////////////////////////
{
__GMM_ASSERT(!(
pTexInfo->Flags.Gpu.Index ||
pTexInfo->Flags.Gpu.RenderTarget ||
pTexInfo->Flags.Gpu.Texture)); // Can explore if needed what combo's make sense--and how req's should combine.
// VERTEX_BUFFER_STATE...
UPDATE_BASE_ALIGNMENT(1); // VB's have member alignment requirements--but it's up to UMD to enforce.
UPDATE_PADDING(1);
}
if(pTexInfo->Flags.Gpu.RenderTarget) //////////////////////////////////////////////////
{
uint32_t ElementSize;
// SURFACE_STATE...
ElementSize = (pTexInfo->BitsPerPixel >> 3) * (GmmIsYUVPacked(pTexInfo->Format) ? 2 : 1);
__GMM_ASSERT((pTexInfo->Pitch % ElementSize) == 0);
UPDATE_BASE_ALIGNMENT(ElementSize);
UPDATE_PADDING(pTexInfo->Pitch * 2); // "Surface Padding Requirements --> Render Target and Media Surfaces"
}
if(pTexInfo->Flags.Gpu.Texture) // (i.e. Sampler Surfaces) ///////////////////////////
{
UPDATE_BASE_ALIGNMENT(1); // Sampler supports byte alignment (with performance hit if misaligned).
if(GetGmmLibContext()->GetWaTable().WaNoMinimizedTrivialSurfacePadding)
{
if(pTexInfo->Type == RESOURCE_BUFFER)
{
if(GetGmmLibContext()->GetWaTable().WaNoBufferSamplerPadding)
{
// Client agreeing to take responsibility for flushing L3 after sampling/etc.
}
else
{
// GMM currently receives GENERIC_8BIT for
// RESOURCE_BUFFER creations, so we have to assume the
// worst-case sample size of 128-bit (unless we alter
// our interface meaning):
uint32_t ElementSize = 16;
// "Surface Padding Requirements --> Sampling Engine Surfaces"
UPDATE_PADDING(ElementSize * ((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) == IGFX_GEN8_CORE) ? 512 : 256));
UPDATE_ADDITIONAL_BYTES(16);
}
}
else // RESOURCE_1D/2D...
{
/* Sampler needs Alignment Unit padding--
but sampler arch confirms that's overly conservative
padding--and for trivial (linear, single-subresource)
2D's, even-row (quad-row on BDW.A0) plus additional
64B padding is sufficient. (E.g. pitch overfetch will
be caught by subsequent rows or the additional 64B. */
__GMM_ASSERT((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) <= IGFX_GEN8_CORE));
if(GmmIsCompressed(GetGmmLibContext(), pTexInfo->Format))
{
// "For compressed textures...padding at the bottom of the surface is to an even compressed row."
UPDATE_PADDING(pTexInfo->Pitch * 2); // (Sampler arch confirmed that even-row is sufficient on BDW despite BDW's 4x4 sampling, since this req is from L2 instead of L1.)
}
else
{
UPDATE_PADDING(pTexInfo->Pitch * ((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) == IGFX_GEN8_CORE) ? 4 : 2)); // Sampler Fetch Rows: BDW ? 4 : 2
}
// "For packed YUV, 96 bpt, 48 bpt, and 24 bpt surface formats, additional padding is required."
if(GmmIsYUVPacked(pTexInfo->Format) || (pTexInfo->BitsPerPixel == 96) || (pTexInfo->BitsPerPixel == 48) || (pTexInfo->BitsPerPixel == 24))
{
UPDATE_ADDITIONAL_BYTES(16);
UPDATE_ADDITIONAL_ROWS(1);
}
/* "For linear surfaces, additional padding of 64
bytes is required at the bottom of the surface."
(Sampler arch confirmed the 64 bytes can overlap with
the other "additional 16 bytes" mentions in that section.) */
UPDATE_ADDITIONAL_BYTES(64);
}
}
else
{
/* For SURFTYPE_BUFFER, SURFTYPE_1D, and
SURFTYPE_2D non-array, non-MSAA, non-mip-mapped surfaces in
linear memory, the only padding requirement is to the next
aligned 64-byte boundary beyond the end of the surface. */
UPDATE_END_ALIGNMENT(64);
}
}
}
else // Gpu.NoRestriction...
{
// Clients specify NoRestriction at their own risk--e.g. it can be
// appropriate when using IA-Coherent L3 combined with L3 being in
// unified/"Rest" mode (where there won't be write-->read-only
// collisions on unintentionally shared cachelines).
}
{ //Finally calculate surf size
GMM_GFX_SIZE_T OriginalEnd, RequiredSize;
ExistingSysMem.pVirtAddress =
(ExistingSysMem.pExistingSysMem & (PAGE_SIZE - 1)) ?
((uint64_t)GFX_ALIGN(ExistingSysMem.pExistingSysMem,
BaseAlignment)) :
ExistingSysMem.pExistingSysMem;
ExistingSysMem.pGfxAlignedVirtAddress =
(uint64_t)GFX_ALIGN(
(uint64_t)ExistingSysMem.pVirtAddress, PAGE_SIZE);
__GMM_ASSERT((ExistingSysMem.pVirtAddress % BaseAlignment) == 0);
RequiredSize = pTexInfo->Pitch * Height;
RequiredSize =
GFX_ALIGN(RequiredSize, SizePadding) +
(AdditionalPaddingRows * pTexInfo->Pitch) +
AdditionalPaddingBytes;
OriginalEnd = ExistingSysMem.pVirtAddress + RequiredSize;
RequiredSize += GFX_ALIGN(OriginalEnd, EndAlignment) - OriginalEnd;
//Ensure sufficient ExistingSysMem available.
if(ExistingSysMem.Size < RequiredSize)
{
return GMM_ERROR;
}
Surf.Size = RequiredSize;
}
GMM_DPF_EXIT;
return GMM_SUCCESS;
}

View File

@ -0,0 +1,179 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#if defined(__linux__) && !LHDM
#include "Internal/Linux/GmmResourceInfoLinInt.h"
/////////////////////////////////////////////////////////////////////////////////////
/// This is an overloaded function to call DeviceCb Function for CreateAllocation
///
/// @param[in] ClientType
/// @param[in] pDeviceCb: Pointer to GMM_DEVICE_CALLBACKS_INT Struct
/// @param[in] pAllocate: Pointer to GMM_DDI_ALLOCATE Union
/// @return Status of CreateAllocation call.
/////////////////////////////////////////////////////////////////////////////////////
int GmmDeviceCallback(GMM_CLIENT ClientType, GMM_DEVICE_CALLBACKS_INT *pDeviceCb, GMM_DDI_ALLOCATE *pAllocate)
{
int Status = 0;
void * pBo = NULL;
void * pCpuAddr = NULL;
uint64_t gpuAddr = 0ULL;
Status = pDeviceCb->DevCbPtrs_.pfnAllocate(pDeviceCb->pBufMgr,
pAllocate->size,
pAllocate->alignment,
&pBo,
&pCpuAddr,
&gpuAddr);
pAllocate->bo = pBo;
pAllocate->cpuAddr = pCpuAddr;
pAllocate->gfxAddr = gpuAddr;
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// This is an overloaded function to call DeviceCb Function for DestroyAllocation
///
/// @param[in] ClientType
/// @param[in] pDeviceCb: Pointer to GMM_DEVICE_CALLBACKS_INT Struct
/// @param[in] pAllocate: Pointer to GMM_DDI_DEALLOCATE Union
/// @return Status of DestroyAllocation call.
/////////////////////////////////////////////////////////////////////////////////////
int GmmDeviceCallback(GMM_CLIENT ClientType, GMM_DEVICE_CALLBACKS_INT *pDeviceCb, GMM_DDI_DEALLOCATE *pDeallocate)
{
int Status = 0;
pDeviceCb->DevCbPtrs_.pfnDeallocate(pDeallocate->bo);
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// This is an overloaded function to call DeviceCb Function for WaitForSyncObjFromCpu
///
/// @param[in] ClientType
/// @param[in] pDeviceCb: Pointer to GMM_DEVICE_CALLBACKS_INT Struct
/// @param[in] pAllocate: Pointer to GMM_DDI_WAITFORSYNCHRONIZATIONOBJECTFROMCPU Union
/// @return Status of WaitForSyncObjFromCpu call.
/////////////////////////////////////////////////////////////////////////////////////
int GmmDeviceCallback(GMM_CLIENT ClientType, GMM_DEVICE_CALLBACKS_INT *pDeviceCb, GMM_DDI_WAITFORSYNCHRONIZATIONOBJECTFROMCPU *pWait)
{
int Status = 0;
pDeviceCb->DevCbPtrs_.pfnWaitFromCpu(pWait->bo);
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function checks for Null DeviceCb Function pointer
///
/// @param[in] ClientType
/// @param[in] pDeviceCb: Pointer to GMM_DEVICE_CALLBACKS_INT Struct
/// @param[in] CallBackType Enum @GMM_DEVICE_CALLBACKS_TYPE
/// @return True if not Null.
/////////////////////////////////////////////////////////////////////////////////////
int GmmCheckForNullDevCbPfn(GMM_CLIENT ClientType, GMM_DEVICE_CALLBACKS_INT *pDeviceCb, GMM_DEVICE_CALLBACKS_TYPE CallBackType)
{
int Status = 0;
switch(CallBackType)
{
case GMM_DEV_CB_ALLOC:
Status = (pDeviceCb->DevCbPtrs_.pfnAllocate != 0);
break;
case GMM_DEV_CB_DEALLOC:
Status = (pDeviceCb->DevCbPtrs_.pfnDeallocate != 0);
break;
case GMM_DEV_CB_WAIT_FROM_CPU:
Status = (pDeviceCb->DevCbPtrs_.pfnWaitFromCpu != 0);
break;
default:
Status = 0;
break;
}
return Status;
}
// Dummy Translation Table Callback for reusing ..
static inline int DummyPrologTranslationTable(void *pDeviceHandle)
{
return 0;
}
static inline int DummyWriteL1Entries(void * pDeviceHandle,
const uint32_t NumEntries,
GMM_GFX_ADDRESS GfxAddress,
uint32_t * Data)
{
return 0;
}
static inline int DummyWriteL2L3Entry(void * pDeviceHandle,
GMM_GFX_ADDRESS GfxAddress,
uint64_t Data)
{
return 0;
}
static inline int DummyWriteFenceID(void * pDeviceHandle,
GMM_GFX_ADDRESS GfxAddress,
uint64_t Data)
{
return 0;
}
static inline int DummyEpilogTranslationTable(void * pDeviceHandle,
uint8_t ForceFlush)
{
return 0;
}
static inline int DummyCopyL1Entry(void * pDeviceHandle,
GMM_GFX_ADDRESS DstGfxAddress,
GMM_GFX_ADDRESS SrcGfxAddress)
{
return 0;
}
static inline int DummyWriteL3Adr(void * pDeviceHandle,
GMM_GFX_ADDRESS L3GfxAddress,
uint64_t RegOffset)
{
return 0;
}
GMM_TRANSLATIONTABLE_CALLBACKS DummyTTCB = {
.pfPrologTranslationTable = DummyPrologTranslationTable,
.pfWriteL1Entries = DummyWriteL1Entries,
.pfWriteL2L3Entry = DummyWriteL2L3Entry,
.pfWriteFenceID = DummyWriteFenceID,
.pfEpilogTranslationTable = DummyEpilogTranslationTable,
.pfCopyL1Entry = DummyCopyL1Entry,
.pfWriteL3Adr = DummyWriteL3Adr,
};
#endif /*__linux__*/

View File

@ -0,0 +1,21 @@
@echo off
REM Copyright(c) 2017 Intel Corporation
REM
REM Permission is hereby granted, free of charge, to any person obtaining a
REM copy of this software and associated documentation files(the "Software"),
REM to deal in the Software without restriction, including without limitation
REM the rights to use, copy, modify, merge, publish, distribute, sublicense,
REM and / or sell copies of the Software, and to permit persons to whom the
REM Software is furnished to do so, subject to the following conditions:
REM
REM The above copyright notice and this permission notice shall be included
REM in all copies or substantial portions of the Software.
REM
REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
REM OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
REM FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
REM THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
REM OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
REM ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
REM OTHER DEALINGS IN THE SOFTWARE.
cscript //nologo %~dp0\GmmCheckCodingStandard.wsf %~dp0\..

View File

@ -0,0 +1,146 @@
//============================================================================
// Copyright(c) 2017 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files(the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and / or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//============================================================================
<job>
<script>
// Globals
var fso = WScript.CreateObject("Scripting.FileSystemObject");
var err_count = 0;
var in_block_comment = false;
// Main function
function main() {
try {
var dir;
// Get the directory to parse from the command-line
{
dir = WScript.Arguments.Unnamed.Item(0);
if (!fso.folderExists(dir)) {
print("ERROR: Cannot find directory " + dir);
err_count++;
return;
}
dir = fso.getAbsolutePathName(dir);
}
print("Checking coding standard in " + dir);
// Loop thru each line of each source file and look for coding standard violations
{
foreach_line(dir, function(file, line, linenum) {
var is_comment_line = false;
if (line.match(/\/\*/)) {
in_block_comment = true;
}
if (line.match(/\*\//)) {
in_block_comment = false;
}
if (line.match(/^\s*\/\//) || in_block_comment) {
is_comment_line = true;
}
if (line.match(/\t/)) {
report_error(file, linenum, "Found tabs. Check your IDE settings and replace tabs with spaces.");
};
})
}
} catch (e) {
print("ERROR: Exception caught in main(). " + e.message);
err_count++;
return;
}
}
// Loops thru each file recursively and applies a function to
// every line
function foreach_line(dir, apply) {
try {
var folder;
// Parse all source files in this directory
{
folder = fso.getFolder(dir);
var files = new Enumerator(folder.Files);
for (; !files.atEnd(); files.moveNext()) {
var path = files.item().path;
var path_l = path.toLowerCase();
if (path_l.match(/(\.cpp|\.hpp|\.h)$/)) {
parse_file(path, apply);
}
}
}
// Recurse through all subfolders
{
var subfolders = new Enumerator(folder.SubFolders);
for (; !subfolders.atEnd(); subfolders.moveNext()) {
foreach_line(subfolders.item().path, apply);
}
}
}
catch (e) {
print("ERROR: Failed to parse directory " + dir + ". " + e.message);
err_count++;
return;
}
}
// Parse every line in the file and applies the
// given function.
function parse_file(path, apply) {
try {
in_block_comment = false;
var f = fso.openTextFile(path, 1);
var i = 0;
while (!f.atEndOfStream) {
i++;
var line = f.readLine();
try {
apply(path, line, i);
} catch(e) {
report_error(path, i, "Failed to parse line. " + e.message);
}
}
f.close();
} catch (e) {
print("ERROR: Failed to open " + path + ". " + e.message);
err_count++;
}
}
// Prints a message
function print(msg) {
WScript.echo(msg);
}
// Prints an error message in a VisualStudio-friendly format
function report_error(file, linenum, msg) {
print(file + "(" + linenum + ") : error : " + msg);
err_count++;
}
main();
print("\nFound " + err_count + " error(s)\n");
WScript.quit(err_count);
</script>
</job>

View File

@ -0,0 +1,941 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "Internal/Common/Texture/GmmGen10TextureCalc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the mip offset of given LOD in Mip Tail
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// MipLevel: given LOD #
///
/// @return offset value of LOD in bytes
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmGen10TextureCalc::GetMipTailByteOffset(GMM_TEXTURE_INFO *pTexInfo,
uint32_t MipLevel)
{
uint32_t ByteOffset = 0, Slot = 0xff;
GMM_DPF_ENTER;
// 3D textures follow the Gen9 mip tail format
if(!pGmmLibContext->GetSkuTable().FtrStandardMipTailFormat || pTexInfo->Type == RESOURCE_3D)
{
return GmmGen9TextureCalc::GetMipTailByteOffset(pTexInfo, MipLevel);
}
if(pTexInfo->Type == RESOURCE_1D)
{
Slot = MipLevel - pTexInfo->Alignment.MipTailStartLod +
(pTexInfo->Flags.Info.TiledYf ? 4 : 0);
}
else if(pTexInfo->Type == RESOURCE_2D || pTexInfo->Type == RESOURCE_CUBE)
{
// clang-format off
Slot = MipLevel - pTexInfo->Alignment.MipTailStartLod +
// TileYs
((pTexInfo->Flags.Info.TiledYs && pTexInfo->MSAA.NumSamples == 16) ? 4 :
(pTexInfo->Flags.Info.TiledYs && pTexInfo->MSAA.NumSamples == 8) ? 3 :
(pTexInfo->Flags.Info.TiledYs && pTexInfo->MSAA.NumSamples == 4) ? 2 :
(pTexInfo->Flags.Info.TiledYs && pTexInfo->MSAA.NumSamples == 2) ? 1 :
(pTexInfo->Flags.Info.TiledYs ) ? 0 :
// TileYf
(pTexInfo->Flags.Info.TiledYf && pTexInfo->MSAA.NumSamples == 16) ? 11:
(pTexInfo->Flags.Info.TiledYf && pTexInfo->MSAA.NumSamples == 8) ? 10:
(pTexInfo->Flags.Info.TiledYf && pTexInfo->MSAA.NumSamples == 4) ? 8:
(pTexInfo->Flags.Info.TiledYf && pTexInfo->MSAA.NumSamples == 2) ? 5:
(pTexInfo->Flags.Info.TiledYf ) ? 4: 0);
// clang-format on
}
switch(Slot)
{
case 0:
ByteOffset = GMM_KBYTE(32);
break;
case 1:
ByteOffset = GMM_KBYTE(16);
break;
case 2:
ByteOffset = GMM_KBYTE(8);
break;
case 3:
ByteOffset = GMM_KBYTE(4);
break;
case 4:
ByteOffset = GMM_KBYTE(2);
break;
case 5:
ByteOffset = GMM_BYTES(1536);
break;
case 6:
ByteOffset = GMM_BYTES(1280);
break;
case 7:
ByteOffset = GMM_BYTES(1024);
break;
case 8:
ByteOffset = GMM_BYTES(768);
break;
case 9:
ByteOffset = GMM_BYTES(512);
break;
case 10:
ByteOffset = GMM_BYTES(256);
break;
case 11:
ByteOffset = GMM_BYTES(192);
break;
case 12:
ByteOffset = GMM_BYTES(128);
break;
case 13:
ByteOffset = GMM_BYTES(64);
break;
case 14:
ByteOffset = GMM_BYTES(0);
break;
default:
__GMM_ASSERT(0);
}
GMM_DPF_EXIT;
return (ByteOffset);
}
GMM_MIPTAIL_SLOT_OFFSET Gen10MipTailSlotOffset1DSurface[15][5] = GEN10_MIPTAIL_SLOT_OFFSET_1D_SURFACE;
GMM_MIPTAIL_SLOT_OFFSET Gen10MipTailSlotOffset2DSurface[15][5] = GEN10_MIPTAIL_SLOT_OFFSET_2D_SURFACE;
GMM_MIPTAIL_SLOT_OFFSET Gen10MipTailSlotOffset3DSurface[15][5] = GEN10_MIPTAIL_SLOT_OFFSET_3D_SURFACE;
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the mip-map offset in geometric OffsetX, Y, Z for a given LOD in Mip Tail.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// MipLevel: mip-map level
/// OffsetX: ptr to Offset in X direction (in bytes)
/// OffsetY: ptr to Offset in Y direction (in pixels)
/// OffsetZ: ptr to Offset in Z direction (in pixels)
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmGen10TextureCalc::GetMipTailGeometryOffset(GMM_TEXTURE_INFO *pTexInfo,
uint32_t MipLevel,
uint32_t * OffsetX,
uint32_t * OffsetY,
uint32_t * OffsetZ)
{
uint32_t ArrayIndex = 0;
uint32_t Slot = 0;
GMM_DPF_ENTER;
// 3D textures follow the Gen9 mip tail format
if(!pGmmLibContext->GetSkuTable().FtrStandardMipTailFormat ||
pTexInfo->Type == RESOURCE_3D)
{
return GmmGen9TextureCalc::GetMipTailGeometryOffset(pTexInfo, MipLevel, OffsetX, OffsetY, OffsetZ);
}
switch(pTexInfo->BitsPerPixel)
{
case 128:
ArrayIndex = 0;
break;
case 64:
ArrayIndex = 1;
break;
case 32:
ArrayIndex = 2;
break;
case 16:
ArrayIndex = 3;
break;
case 8:
ArrayIndex = 4;
break;
default:
__GMM_ASSERT(0);
break;
}
if(pTexInfo->Type == RESOURCE_1D)
{
Slot = MipLevel - pTexInfo->Alignment.MipTailStartLod +
(pTexInfo->Flags.Info.TiledYf ? 4 : 0);
*OffsetX = Gen10MipTailSlotOffset1DSurface[Slot][ArrayIndex].X * pTexInfo->BitsPerPixel / 8;
*OffsetY = Gen10MipTailSlotOffset1DSurface[Slot][ArrayIndex].Y;
*OffsetZ = Gen10MipTailSlotOffset1DSurface[Slot][ArrayIndex].Z;
}
else if(pTexInfo->Type == RESOURCE_2D || pTexInfo->Type == RESOURCE_CUBE)
{
// clang-format off
Slot = MipLevel - pTexInfo->Alignment.MipTailStartLod +
// TileYs
((pTexInfo->Flags.Info.TiledYs && pTexInfo->MSAA.NumSamples == 16) ? 4 :
(pTexInfo->Flags.Info.TiledYs && pTexInfo->MSAA.NumSamples == 8) ? 3 :
(pTexInfo->Flags.Info.TiledYs && pTexInfo->MSAA.NumSamples == 4) ? 2 :
(pTexInfo->Flags.Info.TiledYs && pTexInfo->MSAA.NumSamples == 2) ? 1 :
(pTexInfo->Flags.Info.TiledYs) ? 0 :
// TileYf
(pTexInfo->Flags.Info.TiledYf && pTexInfo->MSAA.NumSamples == 16) ? 11 :
(pTexInfo->Flags.Info.TiledYf && pTexInfo->MSAA.NumSamples == 8) ? 10 :
(pTexInfo->Flags.Info.TiledYf && pTexInfo->MSAA.NumSamples == 4) ? 8 :
(pTexInfo->Flags.Info.TiledYf && pTexInfo->MSAA.NumSamples == 2) ? 5 :
(pTexInfo->Flags.Info.TiledYf) ? 4 : 0);
// clang-format on
*OffsetX = Gen10MipTailSlotOffset2DSurface[Slot][ArrayIndex].X * pTexInfo->BitsPerPixel / 8;
*OffsetY = Gen10MipTailSlotOffset2DSurface[Slot][ArrayIndex].Y;
*OffsetZ = Gen10MipTailSlotOffset2DSurface[Slot][ArrayIndex].Z;
}
GMM_DPF_EXIT;
return;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns the aligned block height of the 3D surface on Gen9
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// BlockHeight:
/// ExpandedArraySize: adjusted array size for MSAA, cube faces, etc.
///
/// @return BlockHeight
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmGen10TextureCalc::GetAligned3DBlockHeight(GMM_TEXTURE_INFO *pTexInfo,
uint32_t BlockHeight,
uint32_t ExpandedArraySize)
{
uint32_t DAlign, CompressHeight, CompressWidth, CompressDepth;
GMM_DPF_ENTER;
__GMM_ASSERTPTR(pTexInfo, 0);
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
DAlign = pTexInfo->Alignment.DAlign;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
if(pTexInfo->Type == RESOURCE_3D)
{
ExpandedArraySize = GFX_ALIGN_NP2(ExpandedArraySize, DAlign) / CompressDepth;
if(!pTexInfo->Flags.Info.Linear)
{
BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
}
}
GMM_DPF_EXIT;
return BlockHeight;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates the 2D mip layout for surface state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: ptr to surface alignment and size restrictions
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen10TextureCalc::FillTex2D(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
uint32_t Width, Height, BitsPerPixel;
uint32_t HAlign, VAlign, DAlign, CompressHeight, CompressWidth, CompressDepth;
uint32_t AlignedWidth, BlockHeight, ExpandedArraySize, Pitch;
uint8_t Compress = 0;
GMM_STATUS Status;
GMM_DPF_ENTER;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pRestrictions, GMM_ERROR);
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
BitsPerPixel = pTexInfo->BitsPerPixel;
if(pTexInfo->Flags.Gpu.CCS && pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
// Aux Surfaces are 8bpp.
BitsPerPixel = 8;
}
Height = pTexInfo->BaseHeight;
Width = GFX_ULONG_CAST(pTexInfo->BaseWidth);
pTexInfo->MSAA.NumSamples = GFX_MAX(pTexInfo->MSAA.NumSamples, 1);
if(pTexInfo->Flags.Info.TiledYf || pTexInfo->Flags.Info.TiledYs)
{
FindMipTailStartLod(pTexInfo);
}
ExpandedArraySize =
GFX_MAX(pTexInfo->ArraySize, 1) *
((pTexInfo->Type == RESOURCE_CUBE) ? 6 : 1) * // Cubemaps simply 6-element, 2D arrays.
((pTexInfo->Type == RESOURCE_3D) ? pTexInfo->Depth : 1) * // 3D's simply 2D arrays.
((pTexInfo->Flags.Gpu.Depth || pTexInfo->Flags.Gpu.SeparateStencil ||
(pTexInfo->Flags.Info.TiledYs || pTexInfo->Flags.Info.TiledYf)) ? // MSAA Ys samples are NOT stored as array planes.
1 :
pTexInfo->MSAA.NumSamples); // MSAA (non-Depth/Stencil) RT samples stored as array planes.
if(pTexInfo->Flags.Info.TiledYs || pTexInfo->Flags.Info.TiledYf)
{
ExpandedArraySize = GFX_CEIL_DIV(ExpandedArraySize, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileDepth);
}
//
// Check for color separation
//
if(pTexInfo->Flags.Gpu.ColorSeparation || pTexInfo->Flags.Gpu.ColorSeparationRGBX)
{
bool csRestrictionsMet = (((ExpandedArraySize <= 2) &&
(ExpandedArraySize == pTexInfo->ArraySize) &&
((pTexInfo->Format == GMM_FORMAT_R8G8B8A8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_R8G8B8A8_UNORM_SRGB) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8A8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8A8_UNORM_SRGB) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8X8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8X8_UNORM_SRGB)) &&
((pTexInfo->Flags.Gpu.ColorSeparation && (Width % 16) == 0) ||
(pTexInfo->Flags.Gpu.ColorSeparationRGBX && (Width % 12) == 0))));
if(csRestrictionsMet)
{
ExpandedArraySize = GMM_COLOR_SEPARATION_ARRAY_SIZE;
}
else
{
pTexInfo->Flags.Gpu.ColorSeparation = false;
pTexInfo->Flags.Gpu.ColorSeparationRGBX = false;
}
}
HAlign = pTexInfo->Alignment.HAlign;
VAlign = pTexInfo->Alignment.VAlign;
DAlign = pTexInfo->Alignment.DAlign;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
/////////////////////////////////
// Calculate Block Surface Height
/////////////////////////////////
if(ExpandedArraySize > 1)
{
uint32_t Alignment = VAlign;
if((pTexInfo->Type == RESOURCE_3D && !pTexInfo->Flags.Info.Linear) ||
(pTexInfo->Flags.Gpu.S3dDx && pGmmLibContext->GetSkuTable().FtrDisplayEngineS3d) ||
(pTexInfo->Flags.Wa.MediaPipeUsage))
{
Alignment = pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight;
//Gmm uses TileY for Stencil allocations, having half TileW height (TileY width compensates)
if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
{
Alignment *= 2;
}
}
// Calculate the overall Block height...Mip0Height + Max(Mip1Height, Sum of Mip2Height..MipnHeight)
BlockHeight = Get2DMipMapTotalHeight(pTexInfo);
BlockHeight = GFX_ALIGN_NP2(BlockHeight, Alignment);
// GMM internally uses QPitch as the logical distance between slices, but translates
// as appropriate to service client queries in GmmResGetQPitch.
pTexInfo->Alignment.QPitch = BlockHeight;
if(Compress)
{
BlockHeight = GFX_CEIL_DIV(BlockHeight, CompressHeight);
BlockHeight = GetAligned3DBlockHeight(pTexInfo, BlockHeight, ExpandedArraySize);
}
else if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
{
BlockHeight /= 2;
}
else if(pTexInfo->Flags.Gpu.CCS && pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
BlockHeight /= 16;
}
BlockHeight *= ExpandedArraySize;
}
else
{
pTexInfo->Alignment.QPitch = 0;
BlockHeight = Get2DMipMapHeight(pTexInfo);
}
///////////////////////////////////
// Calculate Pitch
///////////////////////////////////
AlignedWidth = __GMM_EXPAND_WIDTH(this, Width, HAlign, pTexInfo);
// For Non - planar surfaces, the alignment is done on the entire height of the allocation
if(pGmmLibContext->GetWaTable().WaAlignYUVResourceToLCU &&
GmmIsYUVFormatLCUAligned(pTexInfo->Format))
{
AlignedWidth = GFX_ALIGN(AlignedWidth, GMM_SCANLINES(GMM_MAX_LCU_SIZE));
}
// Calculate special pitch case of small dimensions where LOD1 + LOD2 widths
// are greater than LOD0. e.g. dimensions 4x4 and MinPitch == 1
if((pTexInfo->Flags.Info.TiledYf || pTexInfo->Flags.Info.TiledYs) &&
(pTexInfo->Alignment.MipTailStartLod < 2))
{
// Do nothing -- all mips are in LOD0/LOD1, which is already width aligned.
}
else if(pTexInfo->MaxLod >= 2)
{
uint32_t AlignedWidthLod1, AlignedWidthLod2;
AlignedWidthLod1 = __GMM_EXPAND_WIDTH(this, Width >> 1, HAlign, pTexInfo);
AlignedWidthLod2 = __GMM_EXPAND_WIDTH(this, Width >> 2, HAlign, pTexInfo);
AlignedWidth = GFX_MAX(AlignedWidth, AlignedWidthLod1 + AlignedWidthLod2);
}
if(Compress)
{
AlignedWidth = GFX_CEIL_DIV(AlignedWidth, CompressWidth);
}
else if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
{
AlignedWidth *= 2;
}
else if(pTexInfo->Flags.Gpu.CCS && pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
switch(pTexInfo->BitsPerPixel)
{
case 32:
AlignedWidth /= 8;
break;
case 64:
AlignedWidth /= 4;
break;
case 128:
AlignedWidth /= 2;
break;
default:
__GMM_ASSERT(0);
}
}
else if(pTexInfo->Flags.Gpu.ColorSeparation)
{
AlignedWidth *= pTexInfo->ArraySize;
__GMM_ASSERT(0 == (AlignedWidth % GMM_COLOR_SEPARATION_WIDTH_DIVISION));
AlignedWidth /= GMM_COLOR_SEPARATION_WIDTH_DIVISION;
}
else if(pTexInfo->Flags.Gpu.ColorSeparationRGBX)
{
AlignedWidth *= pTexInfo->ArraySize;
__GMM_ASSERT(0 == (AlignedWidth % GMM_COLOR_SEPARATION_RGBX_WIDTH_DIVISION));
AlignedWidth /= GMM_COLOR_SEPARATION_RGBX_WIDTH_DIVISION;
}
// Default pitch
Pitch = AlignedWidth * BitsPerPixel >> 3;
// Make sure the pitch satisfy linear min pitch requirment
Pitch = GFX_MAX(Pitch, pRestrictions->MinPitch);
// Make sure pitch satisfy alignment restriction
Pitch = GFX_ALIGN(Pitch, pRestrictions->PitchAlignment);
////////////////////
// Adjust for Tiling
////////////////////
if(GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]))
{
Pitch = GFX_ALIGN(Pitch, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileWidth);
BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
}
GMM_ASSERTDPF(pTexInfo->Flags.Info.LayoutBelow || !pTexInfo->Flags.Info.LayoutRight, "MIPLAYOUT_RIGHT not supported after Gen6!");
pTexInfo->Flags.Info.LayoutBelow = 1;
pTexInfo->Flags.Info.LayoutRight = 0;
// If a texture is YUV packed, 96, or 48 bpp then one row plus 16 bytes of
// padding needs to be added. Since this will create a none pitch aligned
// surface the padding is aligned to the next row
if(GmmIsYUVPacked(pTexInfo->Format) ||
(pTexInfo->BitsPerPixel == GMM_BITS(96)) ||
(pTexInfo->BitsPerPixel == GMM_BITS(48)))
{
BlockHeight += GMM_SCANLINES(1) + GFX_CEIL_DIV(GMM_BYTES(16), Pitch);
}
// For Non-planar surfaces, the alignment is done on the entire height of the allocation
if(pGmmLibContext->GetWaTable().WaAlignYUVResourceToLCU &&
GmmIsYUVFormatLCUAligned(pTexInfo->Format) &&
!GmmIsPlanar(pTexInfo->Format))
{
BlockHeight = GFX_ALIGN(BlockHeight, GMM_SCANLINES(GMM_MAX_LCU_SIZE));
}
// Align height to even row to cover for HW over-fetch
BlockHeight = GFX_ALIGN(BlockHeight, __GMM_EVEN_ROW);
if((Status = // <-- Note assignment.
FillTexPitchAndSize(
pTexInfo, Pitch, BlockHeight, pRestrictions)) == GMM_SUCCESS)
{
Fill2DTexOffsetAddress(pTexInfo);
}
GMM_DPF_EXIT;
return (Status);
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function will Setup a planar surface allocation.
///
/// @param[in] pTexInfo: Reference to ::GMM_TEXTURE_INFO
/// @param[in] pRestrictions: Reference to surface alignment and size restrictions.
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen10TextureCalc::FillTexPlanar(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
uint32_t WidthBytesPhysical, Height, YHeight, VHeight;
uint32_t AdjustedVHeight = 0;
GMM_STATUS Status;
bool UVPacked = false;
GMM_DPF_ENTER;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pRestrictions, GMM_ERROR);
__GMM_ASSERT(!pTexInfo->Flags.Info.TiledW);
pTexInfo->TileMode = TILE_NONE;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
WidthBytesPhysical = GFX_ULONG_CAST(pTexInfo->BaseWidth) * pTexInfo->BitsPerPixel >> 3;
Height = VHeight = 0;
YHeight = pTexInfo->BaseHeight;
switch(pTexInfo->Format)
{
case GMM_FORMAT_IMC1: // IMC1 = IMC3 with Swapped U/V
case GMM_FORMAT_IMC3:
case GMM_FORMAT_MFX_JPEG_YUV420: // Same as IMC3.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUU
// UUUU
// VVVV
// VVVV
case GMM_FORMAT_MFX_JPEG_YUV422V: // Similar to IMC3 but U/V are full width.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUUUUU
// UUUUUUUU
// VVVVVVVV
// VVVVVVVV
{
VHeight = GFX_ALIGN(GFX_CEIL_DIV(YHeight, 2), GMM_IMCx_PLANE_ROW_ALIGNMENT);
YHeight = GFX_ALIGN(YHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
Height = YHeight + 2 * VHeight; // One VHeight for V and one for U.
pTexInfo->OffsetInfo.Plane.NoOfPlanes = 3;
break;
}
case GMM_FORMAT_MFX_JPEG_YUV411R_TYPE: //Similar to IMC3 but U/V are quarther height and full width.
//YYYYYYYY
//YYYYYYYY
//YYYYYYYY
//YYYYYYYY
//UUUUUUUU
//VVVVVVVV
{
VHeight = GFX_ALIGN(GFX_CEIL_DIV(YHeight, 4), GMM_IMCx_PLANE_ROW_ALIGNMENT);
YHeight = GFX_ALIGN(YHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
Height = YHeight + 2 * VHeight;
pTexInfo->OffsetInfo.Plane.NoOfPlanes = 3;
break;
}
case GMM_FORMAT_MFX_JPEG_YUV411: // Similar to IMC3 but U/V are quarter width and full height.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UU
// UU
// UU
// UU
// VV
// VV
// VV
// VV
case GMM_FORMAT_MFX_JPEG_YUV422H: // Similar to IMC3 but U/V are full height.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUU
// UUUU
// UUUU
// UUUU
// VVVV
// VVVV
// VVVV
// VVVV
case GMM_FORMAT_BGRP:
case GMM_FORMAT_RGBP:
case GMM_FORMAT_MFX_JPEG_YUV444: // Similar to IMC3 but U/V are full size.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUUUUU
// UUUUUUUU
// UUUUUUUU
// UUUUUUUU
// VVVVVVVV
// VVVVVVVV
// VVVVVVVV
// VVVVVVVV
{
YHeight = GFX_ALIGN(YHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
VHeight = YHeight;
Height = YHeight + 2 * VHeight;
pTexInfo->OffsetInfo.Plane.NoOfPlanes = 3;
break;
}
case GMM_FORMAT_IMC2: // IMC2 = IMC4 with Swapped U/V
case GMM_FORMAT_IMC4:
{
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUVVVV
// UUUUVVVV
YHeight = GFX_ALIGN(YHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
VHeight = GFX_CEIL_DIV(YHeight, 2);
WidthBytesPhysical = GFX_ALIGN(WidthBytesPhysical, 2); // If odd YWidth, pitch bumps-up to fit rounded-up U/V planes.
Height = YHeight + VHeight;
// With SURFACE_STATE.XOffset support, the U-V interface has
// much lighter restrictions--which will be naturally met by
// surface pitch restrictions (i.e. dividing an IMC2/4 pitch
// by 2--to get the U/V interface--will always produce a safe
// XOffset value).
// Not technically UV packed but sizing works out the same
// if the resource is std swizzled
UVPacked = true;
pTexInfo->OffsetInfo.Plane.NoOfPlanes = 2;
break;
}
case GMM_FORMAT_NV12:
case GMM_FORMAT_NV21:
case GMM_FORMAT_NV11:
case GMM_FORMAT_P010:
case GMM_FORMAT_P012:
case GMM_FORMAT_P016:
case GMM_FORMAT_P208:
case GMM_FORMAT_P216:
{
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// [UV-Packing]
if((pTexInfo->Format == GMM_FORMAT_NV12) ||
(pTexInfo->Format == GMM_FORMAT_NV21) ||
(pTexInfo->Format == GMM_FORMAT_P010) ||
(pTexInfo->Format == GMM_FORMAT_P012) ||
(pTexInfo->Format == GMM_FORMAT_P016))
{
VHeight = GFX_CEIL_DIV(YHeight, 2); // U/V plane half of Y
Height = YHeight + VHeight;
}
else
{
VHeight = YHeight; // U/V plane is same as Y
Height = YHeight + VHeight;
}
if((pTexInfo->Format == GMM_FORMAT_NV12) ||
(pTexInfo->Format == GMM_FORMAT_NV21) ||
(pTexInfo->Format == GMM_FORMAT_P010) ||
(pTexInfo->Format == GMM_FORMAT_P012) ||
(pTexInfo->Format == GMM_FORMAT_P016) ||
(pTexInfo->Format == GMM_FORMAT_P208) ||
(pTexInfo->Format == GMM_FORMAT_P216))
{
WidthBytesPhysical = GFX_ALIGN(WidthBytesPhysical, 2); // If odd YWidth, pitch bumps-up to fit rounded-up U/V planes.
}
else //if(pTexInfo->Format == GMM_FORMAT_NV11)
{
// Tiling not supported, since YPitch != UVPitch...
pTexInfo->Flags.Info.TiledY = 0;
pTexInfo->Flags.Info.TiledYf = 0;
pTexInfo->Flags.Info.TiledYs = 0;
pTexInfo->Flags.Info.TiledX = 0;
pTexInfo->Flags.Info.Linear = 1;
}
UVPacked = true;
pTexInfo->OffsetInfo.Plane.NoOfPlanes = 2;
break;
}
case GMM_FORMAT_I420: // IYUV & I420: are identical to YV12 except,
case GMM_FORMAT_IYUV: // U & V pl.s are reversed.
case GMM_FORMAT_YV12:
case GMM_FORMAT_YVU9:
{
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// VVVVVV.. <-- V and U planes follow the Y plane, as linear
// ..UUUUUU arrays--without respect to pitch.
uint32_t YSize, UVSize, YVSizeRShift;
uint32_t YSizeForUVPurposes, YSizeForUVPurposesDimensionalAlignment;
YSize = WidthBytesPhysical * YHeight;
// YVU9 has one U/V pixel for each 4x4 Y block.
// The others have one U/V pixel for each 2x2 Y block.
// YVU9 has a Y:V size ratio of 16 (4x4 --> 1).
// The others have a ratio of 4 (2x2 --> 1).
YVSizeRShift = (pTexInfo->Format != GMM_FORMAT_YVU9) ? 2 : 4;
// If a Y plane isn't fully-aligned to its Y-->U/V block size, the
// extra/unaligned Y pixels still need corresponding U/V pixels--So
// for the purpose of computing the UVSize, we must consider a
// dimensionally "rounded-up" YSize. (E.g. a 13x5 YVU9 Y plane would
// require 4x2 U/V planes--the same UVSize as a fully-aligned 16x8 Y.)
YSizeForUVPurposesDimensionalAlignment = (pTexInfo->Format != GMM_FORMAT_YVU9) ? 2 : 4;
YSizeForUVPurposes =
GFX_ALIGN(WidthBytesPhysical, YSizeForUVPurposesDimensionalAlignment) *
GFX_ALIGN(YHeight, YSizeForUVPurposesDimensionalAlignment);
UVSize = 2 * // <-- U + V
(YSizeForUVPurposes >> YVSizeRShift);
Height = GFX_CEIL_DIV(YSize + UVSize, WidthBytesPhysical);
// Tiling not supported, since YPitch != UVPitch...
pTexInfo->Flags.Info.TiledY = 0;
pTexInfo->Flags.Info.TiledYf = 0;
pTexInfo->Flags.Info.TiledYs = 0;
pTexInfo->Flags.Info.TiledX = 0;
pTexInfo->Flags.Info.Linear = 1;
pTexInfo->OffsetInfo.Plane.NoOfPlanes = 1;
break;
}
default:
{
GMM_ASSERTDPF(0, "Unexpected format");
return GMM_ERROR;
}
}
// Align Height to even row to avoid hang if HW over-fetch
Height = GFX_ALIGN(Height, __GMM_EVEN_ROW);
SetTileMode(pTexInfo);
// MMC is not supported for linear formats.
if(pTexInfo->Flags.Gpu.MMC)
{
if(!(pTexInfo->Flags.Info.TiledY || pTexInfo->Flags.Info.TiledYf || pTexInfo->Flags.Info.TiledYs))
{
pTexInfo->Flags.Gpu.MMC = 0;
}
}
// Legacy Planar "Linear Video" Restrictions...
if(pTexInfo->Flags.Info.Linear && !pTexInfo->Flags.Wa.NoLegacyPlanarLinearVideoRestrictions)
{
pRestrictions->LockPitchAlignment = GFX_MAX(pRestrictions->LockPitchAlignment, GMM_BYTES(64));
pRestrictions->MinPitch = GFX_MAX(pRestrictions->MinPitch, GMM_BYTES(64));
pRestrictions->PitchAlignment = GFX_MAX(pRestrictions->PitchAlignment, GMM_BYTES(64));
pRestrictions->RenderPitchAlignment = GFX_MAX(pRestrictions->RenderPitchAlignment, GMM_BYTES(64));
}
// Multiply overall pitch alignment for surfaces whose U/V planes have a
// pitch down-scaled from that of Y--Since the U/V pitches must meet the
// original restriction, the Y pitch must meet a scaled-up multiple.
if((pTexInfo->Format == GMM_FORMAT_I420) ||
(pTexInfo->Format == GMM_FORMAT_IYUV) ||
(pTexInfo->Format == GMM_FORMAT_NV11) ||
(pTexInfo->Format == GMM_FORMAT_YV12) ||
(pTexInfo->Format == GMM_FORMAT_YVU9))
{
uint32_t LShift =
(pTexInfo->Format != GMM_FORMAT_YVU9) ?
1 : // UVPitch = 1/2 YPitch
2; // UVPitch = 1/4 YPitch
pRestrictions->LockPitchAlignment <<= LShift;
pRestrictions->MinPitch <<= LShift;
pRestrictions->PitchAlignment <<= LShift;
pRestrictions->RenderPitchAlignment <<= LShift;
}
AdjustedVHeight = VHeight;
// In case of Planar surfaces, only the last Plane has to be aligned to 64 for LCU access
if(pGmmLibContext->GetWaTable().WaAlignYUVResourceToLCU && GmmIsYUVFormatLCUAligned(pTexInfo->Format) && VHeight > 0)
{
AdjustedVHeight = GFX_ALIGN(VHeight, GMM_SCANLINES(GMM_MAX_LCU_SIZE));
Height += AdjustedVHeight - VHeight;
}
// For Tiled Planar surfaces, the planes must be tile-boundary aligned.
// Actual alignment is handled in FillPlanarOffsetAddress, but height
// and width must be adjusted for correct size calculation
if(GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]))
{
uint32_t TileHeight = pGmmLibContext->GetPlatformInfo().TileInfo[pTexInfo->TileMode].LogicalTileHeight;
uint32_t TileWidth = pGmmLibContext->GetPlatformInfo().TileInfo[pTexInfo->TileMode].LogicalTileWidth;
pTexInfo->OffsetInfo.Plane.IsTileAlignedPlanes = true;
//for separate U and V planes, use U plane unaligned and V plane aligned
Height = GFX_ALIGN(YHeight, TileHeight) + (UVPacked ? GFX_ALIGN(AdjustedVHeight, TileHeight) :
(GFX_ALIGN(VHeight, TileHeight) + GFX_ALIGN(AdjustedVHeight, TileHeight)));
if(pTexInfo->Format == GMM_FORMAT_IMC2 || // IMC2, IMC4 needs even tile columns
pTexInfo->Format == GMM_FORMAT_IMC4)
{
// If the U & V planes are side-by-side then the surface pitch must be
// padded out so that U and V planes will being on a tile boundary.
// This means that an odd Y plane width must be padded out
// with an additional tile. Even widths do not need padding
uint32_t TileCols = GFX_CEIL_DIV(WidthBytesPhysical, TileWidth);
if(TileCols % 2)
{
WidthBytesPhysical = (TileCols + 1) * TileWidth;
}
}
if(pTexInfo->Flags.Info.TiledYs || pTexInfo->Flags.Info.TiledYf)
{
pTexInfo->Flags.Info.RedecribedPlanes = true;
}
}
// Vary wide planar tiled planar formats do not support MMC pre gen11. All formats do not support
//Special case LKF MMC compressed surfaces
if(pTexInfo->Flags.Gpu.MMC &&
pTexInfo->Flags.Gpu.UnifiedAuxSurface &&
pTexInfo->Flags.Info.TiledY)
{
uint32_t TileHeight = pGmmLibContext->GetPlatformInfo().TileInfo[pTexInfo->TileMode].LogicalTileHeight;
Height = GFX_ALIGN(YHeight, TileHeight) + GFX_ALIGN(AdjustedVHeight, TileHeight);
}
// Vary wide planar tiled planar formats do not support MMC pre gen11. All formats do not support
// MMC above 16k bytes wide, while Yf NV12 does not support above 8k - 128 bytes.
if((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) <= IGFX_GEN10_CORE) &&
(pTexInfo->Flags.Info.TiledY || pTexInfo->Flags.Info.TiledYf || pTexInfo->Flags.Info.TiledYs))
{
if(((pTexInfo->BaseWidth * pTexInfo->BitsPerPixel / 8) >= GMM_KBYTE(16)) ||
(pTexInfo->Format == GMM_FORMAT_NV12 && pTexInfo->Flags.Info.TiledYf &&
(pTexInfo->BaseWidth * pTexInfo->BitsPerPixel / 8) >= (GMM_KBYTE(8) - 128)))
{
pTexInfo->Flags.Gpu.MMC = 0;
}
}
if(pTexInfo->Flags.Info.RedecribedPlanes)
{
if(false == RedescribeTexturePlanes(pTexInfo, &WidthBytesPhysical))
{
__GMM_ASSERT(FALSE);
}
}
if((Status = // <-- Note assignment.
FillTexPitchAndSize(
pTexInfo, WidthBytesPhysical, Height, pRestrictions)) == GMM_SUCCESS)
{
FillPlanarOffsetAddress(pTexInfo);
}
// Planar & hybrid 2D arrays supported in DX11.1+ spec but not HW. Memory layout
// is defined by SW requirements; Y plane must be 4KB aligned.
if(pTexInfo->ArraySize > 1)
{
GMM_GFX_SIZE_T ElementSizeBytes = pTexInfo->Size;
int64_t LargeSize;
// Size should always be page aligned.
__GMM_ASSERT((pTexInfo->Size % PAGE_SIZE) == 0);
if((LargeSize = (int64_t)ElementSizeBytes * pTexInfo->ArraySize) <= pPlatform->SurfaceMaxSize)
{
pTexInfo->OffsetInfo.Plane.ArrayQPitch = ElementSizeBytes;
pTexInfo->Size = LargeSize;
}
else
{
GMM_ASSERTDPF(0, "Surface too large!");
Status = GMM_ERROR;
}
}
GMM_DPF_EXIT;
return (Status);
} // FillTexPlanar

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,907 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates the 2D mip layout for surface state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: ptr to surface alignment and size restrictions
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen7TextureCalc::FillTex2D(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
uint32_t Width, Height, BitsPerPixel;
uint32_t HAlign, VAlign;
uint32_t CompressHeight, CompressWidth, CompressDepth;
uint32_t AlignedWidth, BlockHeight, ExpandedArraySize, Pitch;
uint8_t Compress = 0;
GMM_STATUS Status;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pRestrictions, GMM_ERROR);
GMM_DPF_ENTER;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
BitsPerPixel = pTexInfo->BitsPerPixel;
Height = pTexInfo->BaseHeight;
Width = GFX_ULONG_CAST(pTexInfo->BaseWidth);
pTexInfo->MSAA.NumSamples = GFX_MAX(pTexInfo->MSAA.NumSamples, 1);
ExpandedArraySize =
GFX_MAX(pTexInfo->ArraySize, 1) *
((pTexInfo->Type == RESOURCE_CUBE) ? 6 : 1) * // Cubemaps simply 6-element, 2D arrays.
((pTexInfo->Flags.Gpu.Depth || pTexInfo->Flags.Gpu.SeparateStencil) ?
1 :
pTexInfo->MSAA.NumSamples); // Gen7 MSAA (non-Depth/Stencil) RT samples stored as array planes.
//
// Check for color separation
//
if(pTexInfo->Flags.Gpu.ColorSeparation || pTexInfo->Flags.Gpu.ColorSeparationRGBX)
{
bool csRestrictionsMet = (((ExpandedArraySize <= 2) &&
(ExpandedArraySize == pTexInfo->ArraySize) &&
((pTexInfo->Format == GMM_FORMAT_R8G8B8A8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_R8G8B8A8_UNORM_SRGB) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8A8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8A8_UNORM_SRGB) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8X8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8X8_UNORM_SRGB)) &&
((pTexInfo->Flags.Gpu.ColorSeparation && (Width % 16) == 0) ||
(pTexInfo->Flags.Gpu.ColorSeparationRGBX && (Width % 12) == 0))));
if(csRestrictionsMet)
{
ExpandedArraySize = GMM_COLOR_SEPARATION_ARRAY_SIZE;
}
else
{
pTexInfo->Flags.Gpu.ColorSeparation = 0;
pTexInfo->Flags.Gpu.ColorSeparationRGBX = 0;
}
}
HAlign = pTexInfo->Alignment.HAlign;
VAlign = pTexInfo->Alignment.VAlign;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
/////////////////////////////////
// Calculate Block Surface Height
/////////////////////////////////
// Adjust total height for arrayed 2D textures
if(ExpandedArraySize > 1)
{
uint32_t Height0, Height1;
Height0 = __GMM_EXPAND_HEIGHT(this, Height, VAlign, pTexInfo);
// If not ARYSPC_LOD0-eligible...
if((pTexInfo->MaxLod > 0) ||
pTexInfo->Flags.Gpu.Depth || // Depth/HiZ/Stencil buffers not ARYSPC_LOD0-compatible.
pTexInfo->Flags.Gpu.HiZ ||
pTexInfo->Flags.Gpu.SeparateStencil)
{
Height1 = __GMM_EXPAND_HEIGHT(this, Height >> 1, VAlign, pTexInfo);
// QPitch = (h0 + h1 + 12j) * pitch
BlockHeight = Height0 + Height1 + 12 * VAlign;
}
else // SURFACE_STATE: Surface Array Spacing: ARYSPC_LOD0
{
// QPitch = h0 * pitch
BlockHeight = Height0;
pTexInfo->Alignment.ArraySpacingSingleLod = true;
}
if(Compress)
{
BlockHeight /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
BlockHeight /= 2;
}
// Compute total array height
BlockHeight *= ExpandedArraySize;
}
else
{
BlockHeight = Get2DMipMapHeight(pTexInfo);
}
///////////////////////////////////
// Calculate Pitch
///////////////////////////////////
AlignedWidth = __GMM_EXPAND_WIDTH(this, Width, HAlign, pTexInfo);
// Calculate special pitch case of small dimensions where LOD1 + LOD2 widths are greater
// than LOD0. e.g. dimensions 4x4 and MinPitch == 1
if(pTexInfo->MaxLod >= 2)
{
uint32_t AlignedWidthLod1, AlignedWidthLod2;
AlignedWidthLod1 = __GMM_EXPAND_WIDTH(this, Width >> 1, HAlign, pTexInfo);
AlignedWidthLod2 = __GMM_EXPAND_WIDTH(this, Width >> 2, HAlign, pTexInfo);
AlignedWidth = GFX_MAX(AlignedWidth, AlignedWidthLod1 + AlignedWidthLod2);
}
if(Compress)
{
AlignedWidth /= CompressWidth;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
AlignedWidth *= 2;
}
else if(pTexInfo->Flags.Gpu.ColorSeparation)
{
AlignedWidth *= pTexInfo->ArraySize;
__GMM_ASSERT(0 == (AlignedWidth % GMM_COLOR_SEPARATION_WIDTH_DIVISION));
AlignedWidth /= GMM_COLOR_SEPARATION_WIDTH_DIVISION;
}
else if(pTexInfo->Flags.Gpu.ColorSeparationRGBX)
{
AlignedWidth *= pTexInfo->ArraySize;
__GMM_ASSERT(0 == (AlignedWidth % GMM_COLOR_SEPARATION_RGBX_WIDTH_DIVISION));
AlignedWidth /= GMM_COLOR_SEPARATION_RGBX_WIDTH_DIVISION;
}
// Default pitch
Pitch = AlignedWidth * BitsPerPixel >> 3;
// Make sure the pitch satisfy linear min pitch requirment
Pitch = GFX_MAX(Pitch, pRestrictions->MinPitch);
// Make sure pitch satisfy alignment restriction
Pitch = GFX_ALIGN(Pitch, pRestrictions->PitchAlignment);
////////////////////
// Adjust for Tiling
////////////////////
if(GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]))
{
Pitch = GFX_ALIGN(Pitch, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileWidth);
BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
// If Tiled Resource or Undefined64KBSwizzle resource, align to 64KB tile size
if((pTexInfo->Flags.Gpu.TiledResource || pTexInfo->Flags.Info.Undefined64KBSwizzle) &&
(pTexInfo->Flags.Info.TiledY))
{
uint32_t ColFactor = 0, RowFactor = 0;
uint32_t TRTileWidth = 0, TRTileHeight = 0;
GmmGetD3DToHwTileConversion(pTexInfo, &ColFactor, &RowFactor);
TRTileWidth = pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileWidth * ColFactor;
TRTileHeight = pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight * RowFactor;
Pitch = GFX_ALIGN(Pitch, TRTileWidth);
BlockHeight = GFX_ALIGN(BlockHeight, TRTileHeight);
}
}
GMM_ASSERTDPF(pTexInfo->Flags.Info.LayoutBelow || !pTexInfo->Flags.Info.LayoutRight, "MIPLAYOUT_RIGHT not supported after Gen6!");
pTexInfo->Flags.Info.LayoutBelow = 1;
pTexInfo->Flags.Info.LayoutRight = 0;
// If a texture is YUV packed, 96, or 48 bpp then one row plus 16 bytes of
// padding needs to be added. Since this will create a none pitch aligned
// surface the padding is aligned to the next row
if(GmmIsYUVPacked(pTexInfo->Format) ||
(pTexInfo->BitsPerPixel == GMM_BITS(96)) ||
(pTexInfo->BitsPerPixel == GMM_BITS(48)))
{
BlockHeight += GMM_SCANLINES(1) + GFX_CEIL_DIV(GMM_BYTES(16), Pitch);
}
// Align height to even row to cover for HW over - fetch
BlockHeight = GFX_ALIGN(BlockHeight, __GMM_EVEN_ROW);
if((Status = // <-- Note assignment.
FillTexPitchAndSize(
pTexInfo, Pitch, BlockHeight, pRestrictions)) == GMM_SUCCESS)
{
Fill2DTexOffsetAddress(pTexInfo);
// Init to no-packed mips. It'll be initialized when app calls to get packed
// mips. Calculate packed mips here if there's a chance apps won't call to
// get packed mips.
pTexInfo->Alignment.PackedMipStartLod = GMM_TILED_RESOURCE_NO_PACKED_MIPS;
}
GMM_DPF_EXIT;
return (Status);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates the mip offset of given LOD in 2D mip layout
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
///
/// @return offset value in bytes
/////////////////////////////////////////////////////////////////////////////////////
GMM_GFX_SIZE_T GmmLib::GmmGen7TextureCalc::Get2DTexOffsetAddressPerMip(GMM_TEXTURE_INFO *pTexInfo,
uint32_t MipLevel)
{
GMM_GFX_SIZE_T MipOffset;
uint32_t AlignedMipHeight, i, MipHeight, OffsetHeight;
uint32_t HAlign, VAlign;
uint32_t CompressHeight, CompressWidth, CompressDepth;
uint8_t Compress;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
GMM_DPF_ENTER;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
HAlign = pTexInfo->Alignment.HAlign;
VAlign = pTexInfo->Alignment.VAlign;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
MipHeight = pTexInfo->BaseHeight;
OffsetHeight = 0;
// Mips 0 and 1 are on the left edge...
if(MipLevel < 2)
{
MipOffset = 0;
}
else // Mip2 and beyond are to the right of Mip1...
{
uint32_t Mip1Width = GFX_ULONG_CAST(pTexInfo->BaseWidth) >> 1;
Mip1Width = __GMM_EXPAND_WIDTH(this, Mip1Width, HAlign, pTexInfo);
if(Compress)
{
Mip1Width /= CompressWidth;
if((pGmmLibContext->GetWaTable().WaAstcCorruptionForOddCompressedBlockSizeX || pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips) && pPlatform->FormatTable[pTexInfo->Format].ASTC && CompressWidth == 5)
{
uint32_t Width1 = (pTexInfo->BaseWidth == 1) ? 1 : (GFX_ULONG_CAST(pTexInfo->BaseWidth) >> 1);
uint32_t Modulo10 = Width1 % 10;
if(Modulo10 >= 1 && Modulo10 <= CompressWidth)
{
Mip1Width += 3;
}
}
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
Mip1Width *= 2;
}
MipOffset = (GMM_GFX_SIZE_T)Mip1Width * pTexInfo->BitsPerPixel >> 3;
}
for(i = 1; i <= MipLevel; i++)
{
AlignedMipHeight = GFX_ULONG_CAST(__GMM_EXPAND_HEIGHT(this, MipHeight, VAlign, pTexInfo));
if(Compress)
{
AlignedMipHeight /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
AlignedMipHeight /= 2;
}
OffsetHeight += ((i != 2) ? AlignedMipHeight : 0);
MipHeight >>= 1;
}
MipOffset += OffsetHeight * GFX_ULONG_CAST(pTexInfo->Pitch);
GMM_DPF_EXIT;
return (MipOffset);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates height of the 2D mip layout
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
///
/// @return Height of 2D mip layout
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmGen7TextureCalc::Get2DMipMapHeight(GMM_TEXTURE_INFO *pTexInfo)
{
uint32_t Height, BlockHeight, NumLevels; // Final height for 2D surface
uint32_t HeightLines, HeightLinesLevel0, HeightLinesLevel1, HeightLinesLevel2;
uint32_t VAlign, CompressHeight, CompressWidth, CompressDepth;
uint32_t i;
uint8_t Compress;
GMM_DPF_ENTER;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
// Mip 0 height is needed later
Height = pTexInfo->BaseHeight;
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
NumLevels = pTexInfo->MaxLod;
HeightLines = Height;
VAlign = pTexInfo->Alignment.VAlign;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
HeightLinesLevel0 = __GMM_EXPAND_HEIGHT(this, HeightLines, VAlign, pTexInfo);
if(Compress)
{
HeightLinesLevel0 /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
HeightLinesLevel0 /= 2;
}
// Start out with mip0
BlockHeight = HeightLinesLevel0;
// Height of mip1 and height of all others mips(2,3,4,5,,) needed later
HeightLinesLevel1 = HeightLinesLevel2 = 0;
for(i = 1; i <= NumLevels; i++)
{
uint32_t AlignedHeightLines;
HeightLines >>= 1;
AlignedHeightLines = __GMM_EXPAND_HEIGHT(this, HeightLines, VAlign, pTexInfo);
if(Compress)
{
AlignedHeightLines /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
AlignedHeightLines /= 2;
}
if(i == 1)
{
HeightLinesLevel1 = AlignedHeightLines;
}
else
{
HeightLinesLevel2 += AlignedHeightLines;
}
}
// If mip1 height covers all others then that is all we need
if(HeightLinesLevel1 >= HeightLinesLevel2)
{
BlockHeight += GFX_ALIGN_NP2(HeightLinesLevel1, VAlign);
}
else
{
BlockHeight += GFX_ALIGN_NP2(HeightLinesLevel2, VAlign);
}
GMM_DPF_EXIT;
return (BlockHeight);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates the address offset for each mip map of 2D texture and store them
/// into the GMM_TEXTURE_INFO for surf state programming.
///
/// @param[in] pTexInfo: pointer to ::GMM_TEXTURE_INFO
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmGen7TextureCalc::Fill2DTexOffsetAddress(GMM_TEXTURE_INFO *pTexInfo)
{
uint32_t i;
__GMM_ASSERTPTR(pTexInfo, VOIDRETURN);
GMM_DPF_ENTER;
// QPitch: Array Element-to-Element, or Cube Face-to-Face Pitch...
// -------------------------------------------------------------------------
// Note: Gen7 MSAA RT samples stored as contiguous array planes--
// e.g. MSAA-4X'ed array elements A and B stored: A0 A1 A2 A3 B0 B1 B2 B3.
// However, for GMM's purposes QPitch is still the distance between
// elements--not the distance between samples.
// -------------------------------------------------------------------------
if((pTexInfo->ArraySize <= 1) &&
(pTexInfo->Type != RESOURCE_CUBE) &&
!(pTexInfo->Flags.Gpu.ColorSeparation ||
pTexInfo->Flags.Gpu.ColorSeparationRGBX))
{
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender = 0;
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock = 0;
}
else
{
uint32_t Height, Height0, Height1, ArrayQPitch, VAlign;
Height = pTexInfo->BaseHeight;
VAlign = pTexInfo->Alignment.VAlign;
Height0 = __GMM_EXPAND_HEIGHT(this, Height, VAlign, pTexInfo);
Height1 = __GMM_EXPAND_HEIGHT(this, Height >> 1, VAlign, pTexInfo);
if(!pTexInfo->Alignment.ArraySpacingSingleLod)
{
// QPitch = (h0 + h1 + 12j) * pitch
ArrayQPitch = Height0 + Height1 + 12 * VAlign;
}
else // SURFACE_STATE: Surface Array Spacing: ARYSPC_LOD0
{
// QPitch = h0 * pitch
ArrayQPitch = Height0;
}
if(GmmIsCompressed(pGmmLibContext, pTexInfo->Format))
{
uint32_t CompressHeight, CompressWidth, CompressDepth;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
ArrayQPitch /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
ArrayQPitch /= 2;
}
if((pTexInfo->MSAA.NumSamples > 1) && !(pTexInfo->Flags.Gpu.Depth || pTexInfo->Flags.Gpu.SeparateStencil))
{
// Gen7 MSAA (non-Depth/Stencil) RT samples stored as array planes;
// QPitch still element-to-element, not sample-to-sample.
ArrayQPitch *= pTexInfo->MSAA.NumSamples;
}
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender = ArrayQPitch * pTexInfo->Pitch;
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock = ArrayQPitch * pTexInfo->Pitch;
}
for(i = 0; i <= pTexInfo->MaxLod; i++)
{
pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[i] = Get2DTexOffsetAddressPerMip(pTexInfo, i);
}
GMM_DPF_EXIT;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates total height of an arrayed 3D mip layout
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
///
/// @return height of arrayed 3D mip layout
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmGen7TextureCalc::GetTotal3DHeight(GMM_TEXTURE_INFO *pTexInfo)
{
uint32_t AlignedHeight, BlockHeight, Depth;
uint8_t Compressed;
uint32_t i, MipsInThisRow, MipLevel, MipRows;
uint32_t Total3DHeight = 0, UnitAlignHeight;
uint32_t CompressHeight, CompressWidth, CompressDepth;
GMM_TEXTURE_CALC *pTextureCalc;
GMM_DPF_ENTER;
pTextureCalc = GMM_OVERRIDE_TEXTURE_CALC(pTexInfo, pGmmLibContext);
BlockHeight = pTexInfo->BaseHeight;
Depth = pTexInfo->Depth;
MipLevel = pTexInfo->MaxLod;
UnitAlignHeight = pTexInfo->Alignment.VAlign;
Compressed = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
pTextureCalc->GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
// All mip0s of all planes are stacked together, then mip1s and so on...
for(i = 0; i <= MipLevel; i++)
{
BlockHeight = GFX_MAX(BlockHeight, UnitAlignHeight);
AlignedHeight = GFX_ALIGN(BlockHeight, UnitAlignHeight);
if(Compressed)
{
AlignedHeight /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
AlignedHeight /= 2;
}
else if(pTexInfo->Flags.Gpu.CCS)
{
if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
AlignedHeight /= 32;
}
else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
{
AlignedHeight /= 16;
}
}
// See how many mip can fit in one row
MipsInThisRow = GFX_2_TO_POWER_OF(i);
// calculate if the mips will spill over to multiple rows
MipRows = GFX_CEIL_DIV(GFX_MAX(1, Depth >> i), MipsInThisRow);
Total3DHeight += MipRows * AlignedHeight;
// next level height
BlockHeight >>= 1;
}
GMM_DPF_EXIT;
return Total3DHeight;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates the address offset for each mip map of 3D texture and store them
/// into the GMM_TEXTURE_INFO for surf state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmGen7TextureCalc::Fill3DTexOffsetAddress(GMM_TEXTURE_INFO *pTexInfo)
{
uint32_t AlignedMipHeight, AlignedMipWidth;
uint32_t i, Depth;
uint32_t MipsInThisRow, MipLevel, MipRows;
uint32_t MipHeight, MipWidth;
uint32_t UnitAlignHeight, UnitAlignWidth;
uint32_t CompressHeight, CompressWidth, CompressDepth;
uint32_t OffsetMipRows = 0;
GMM_GFX_SIZE_T OffsetValue;
uint8_t Compress;
GMM_TEXTURE_CALC *pTextureCalc;
__GMM_ASSERT(pTexInfo);
pTextureCalc = GMM_OVERRIDE_TEXTURE_CALC(pTexInfo, pGmmLibContext);
// Assign directly to unaligned MipMap dimension variables
// There isn't a need to save original dimensions
MipWidth = GFX_ULONG_CAST(pTexInfo->BaseWidth);
MipHeight = pTexInfo->BaseHeight;
// Align before we compress
UnitAlignWidth = pTexInfo->Alignment.HAlign;
UnitAlignHeight = pTexInfo->Alignment.VAlign;
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
pTextureCalc->GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
// Aligned MipMap Dimensions
AlignedMipWidth = GFX_ALIGN(MipWidth, UnitAlignWidth);
AlignedMipHeight = GFX_ALIGN(MipHeight, UnitAlignHeight);
Depth = pTexInfo->Depth;
MipLevel = pTexInfo->MaxLod;
// Start with base offset
OffsetValue = 0;
// calculate the offset for each Mip level
for(i = 0; i <= MipLevel; i++)
{
// store the value in blockdesc
if(Compress)
{
// If there is compression, compress after the alignment at each level
AlignedMipWidth /= CompressWidth;
AlignedMipHeight /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
AlignedMipWidth *= 2;
AlignedMipHeight /= 2;
}
else if(pTexInfo->Flags.Gpu.CCS)
{
if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
switch(pTexInfo->BitsPerPixel)
{
case 32:
AlignedMipWidth /= 8;
break;
case 64:
AlignedMipWidth /= 4;
break;
case 128:
AlignedMipWidth /= 2;
break;
default:
__GMM_ASSERT(0);
}
AlignedMipHeight /= 32;
}
else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
{
switch(pTexInfo->BitsPerPixel)
{
case 32:
AlignedMipWidth /= 16;
break;
case 64:
AlignedMipWidth /= 8;
break;
case 128:
AlignedMipWidth /= 4;
break;
default:
__GMM_ASSERT(0);
}
AlignedMipHeight /= 16;
}
}
pTexInfo->OffsetInfo.Texture3DOffsetInfo.Offset[i] = OffsetValue;
// See how many mip can fit in one row
MipsInThisRow = GFX_2_TO_POWER_OF(i);
// Slice pitch for LOD0
if(MipsInThisRow == 1)
{
pTexInfo->OffsetInfo.Texture3DOffsetInfo.Mip0SlicePitch =
AlignedMipHeight * pTexInfo->Pitch;
}
// calculate if the mips will spill over to multiple rows
MipRows = GFX_CEIL_DIV(GFX_MAX(1, Depth >> i), MipsInThisRow);
// Offset in terms of height
OffsetMipRows += MipRows * AlignedMipHeight;
// For a particular mip This is offset of a base slice (i.e. Slice 0)
OffsetValue = OffsetMipRows * pTexInfo->Pitch;
// next level height
MipHeight >>= 1;
// Clamp such that mip height is at least1
MipHeight = GFX_MAX(MipHeight, 1);
AlignedMipHeight = GFX_ALIGN(MipHeight, UnitAlignHeight);
MipWidth >>= 1;
// Clamp such that mip width is at least 1
MipWidth = GFX_MAX(MipWidth, 1);
AlignedMipWidth = GFX_ALIGN(MipWidth, UnitAlignWidth);
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates the 3D offset and QPitch for surface state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: ptr to surface alignment and size restrictions
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen7TextureCalc::FillTex3D(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
uint32_t AlignedMipWidth;
uint32_t BitsPerPixel;
uint32_t Depth, Height, Width;
uint32_t i, MipsInThisRow, MipWidth;
uint32_t RenderPitch = 0, ThisRowPitch;
uint32_t UnitAlignWidth;
uint32_t Total3DHeight;
uint32_t WidthBytesPhysical;
uint8_t Compress;
uint32_t CompressHeight, CompressWidth, CompressDepth;
bool SeparateStencil;
GMM_STATUS Status;
GMM_DPF_ENTER;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pRestrictions, GMM_ERROR);
const __GMM_PLATFORM_RESOURCE *pPlatformResource = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
BitsPerPixel = pTexInfo->BitsPerPixel;
Height = pTexInfo->BaseHeight;
Width = GFX_ULONG_CAST(pTexInfo->BaseWidth);
Depth = pTexInfo->Depth;
// Align before we compress
UnitAlignWidth = pTexInfo->Alignment.HAlign;
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
SeparateStencil = pTexInfo->Flags.Gpu.SeparateStencil ? true : false;
// Unaligned MipMap dimension variables
MipWidth = Width;
// Aligned MipMap dimension variables
AlignedMipWidth = GFX_ALIGN(MipWidth, UnitAlignWidth);
// Calculate the render pitch exactly the same way we do the
// offset for each Mip level
for(i = 0; i <= pTexInfo->MaxLod; i++)
{
if(Compress)
{
// If there is compression, compress after the alignment at each level
AlignedMipWidth /= CompressWidth;
}
else if(SeparateStencil)
{
AlignedMipWidth *= 2;
}
else if(pTexInfo->Flags.Gpu.CCS)
{
if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
switch(BitsPerPixel)
{
case 32:
AlignedMipWidth /= 8;
break;
case 64:
AlignedMipWidth /= 4;
break;
case 128:
AlignedMipWidth /= 2;
break;
default:
__GMM_ASSERT(0);
}
}
else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
{
switch(BitsPerPixel)
{
case 32:
AlignedMipWidth /= 16;
break;
case 64:
AlignedMipWidth /= 8;
break;
case 128:
AlignedMipWidth /= 4;
break;
default:
__GMM_ASSERT(0);
}
}
}
// See how many mip can fit in one row
MipsInThisRow = GFX_2_TO_POWER_OF(i);
// LOD planes may be less than MipsInThisRow, take the smaller value for pitch
MipsInThisRow = GFX_MIN(GFX_MAX(1, (Depth >> i)), MipsInThisRow);
ThisRowPitch = AlignedMipWidth * MipsInThisRow;
// Default pitch
WidthBytesPhysical = ThisRowPitch * BitsPerPixel >> 3;
if(RenderPitch < WidthBytesPhysical)
{
RenderPitch = WidthBytesPhysical;
}
MipWidth >>= 1;
// Clamp such that mip width is at least 1
MipWidth = GFX_MAX(MipWidth, 1);
AlignedMipWidth = GFX_ALIGN(MipWidth, UnitAlignWidth);
}
WidthBytesPhysical = RenderPitch;
// Make sure the pitch satisfy linear min pitch requirment
WidthBytesPhysical = GFX_MAX(WidthBytesPhysical,
pRestrictions->MinPitch);
// Make sure pitch satisfy alignment restriction
WidthBytesPhysical = GFX_ALIGN(WidthBytesPhysical,
pRestrictions->PitchAlignment);
// Get Total height for the entire 3D texture
Total3DHeight = GetTotal3DHeight(pTexInfo);
if(GMM_IS_TILED(pPlatformResource->TileInfo[pTexInfo->TileMode]))
{
// Align to tile boundary
Total3DHeight = GFX_ALIGN(Total3DHeight,
pPlatformResource->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
WidthBytesPhysical = GFX_ALIGN(WidthBytesPhysical,
pPlatformResource->TileInfo[pTexInfo->TileMode].LogicalTileWidth);
}
// If a texture is YUV packed, 96, or 48 bpp then one row plus 16 bytes of
// padding needs to be added. Since this will create a none pitch aligned
// surface the padding is aligned to the next row
if(GmmIsYUVPacked(pTexInfo->Format) ||
(pTexInfo->BitsPerPixel == GMM_BITS(96)) ||
(pTexInfo->BitsPerPixel == GMM_BITS(48)))
{
Total3DHeight += GMM_SCANLINES(1) + GFX_CEIL_DIV(GMM_BYTES(16), WidthBytesPhysical);
}
Total3DHeight = GFX_ALIGN(Total3DHeight, __GMM_EVEN_ROW);
if((Status = // <-- Note assignment.
FillTexPitchAndSize(
pTexInfo, WidthBytesPhysical, Total3DHeight, pRestrictions)) == GMM_SUCCESS)
{
Fill3DTexOffsetAddress(pTexInfo);
}
GMM_DPF_EXIT;
return (Status);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates the 1D mip layout for surface state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: ptr to surface alignment and size restrictions
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen7TextureCalc::FillTex1D(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
return FillTex2D(pTexInfo, pRestrictions);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates the cube layout for surface state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: ptr to surface alignment and size restrictions
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen7TextureCalc::FillTexCube(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
return FillTex2D(pTexInfo, pRestrictions);
}

View File

@ -0,0 +1,498 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates the 2D mip layout for surface state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: ptr to surface alignment and size restrictions
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen8TextureCalc::FillTex2D(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
uint32_t Width, Height, BitsPerPixel;
uint32_t HAlign, VAlign;
uint32_t CompressHeight, CompressWidth, CompressDepth;
uint32_t AlignedWidth, BlockHeight, ExpandedArraySize, Pitch;
uint8_t Compress = 0;
GMM_STATUS Status;
GMM_DPF_ENTER;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pRestrictions, GMM_ERROR);
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
BitsPerPixel = pTexInfo->BitsPerPixel;
Height = pTexInfo->BaseHeight;
Width = GFX_ULONG_CAST(pTexInfo->BaseWidth);
pTexInfo->MSAA.NumSamples = GFX_MAX(pTexInfo->MSAA.NumSamples, 1);
ExpandedArraySize =
GFX_MAX(pTexInfo->ArraySize, 1) *
((pTexInfo->Type == RESOURCE_CUBE) ? 6 : 1) * // Cubemaps simply 6-element, 2D arrays.
((pTexInfo->Flags.Gpu.Depth || pTexInfo->Flags.Gpu.SeparateStencil) ?
1 :
pTexInfo->MSAA.NumSamples); // MSAA (non-Depth/Stencil) RT samples stored as array planes.
//
// Check for color separation
//
if(pTexInfo->Flags.Gpu.ColorSeparation || pTexInfo->Flags.Gpu.ColorSeparationRGBX)
{
bool csRestrictionsMet = (((ExpandedArraySize <= 2) &&
(ExpandedArraySize == pTexInfo->ArraySize) &&
((pTexInfo->Format == GMM_FORMAT_R8G8B8A8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_R8G8B8A8_UNORM_SRGB) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8A8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8A8_UNORM_SRGB) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8X8_UNORM) ||
(pTexInfo->Format == GMM_FORMAT_B8G8R8X8_UNORM_SRGB)) &&
((pTexInfo->Flags.Gpu.ColorSeparation && (Width % 16) == 0) ||
(pTexInfo->Flags.Gpu.ColorSeparationRGBX && (Width % 12) == 0))));
if(csRestrictionsMet)
{
ExpandedArraySize = GMM_COLOR_SEPARATION_ARRAY_SIZE;
}
else
{
pTexInfo->Flags.Gpu.ColorSeparation = 0;
pTexInfo->Flags.Gpu.ColorSeparationRGBX = 0;
}
}
HAlign = pTexInfo->Alignment.HAlign;
VAlign = pTexInfo->Alignment.VAlign;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
// Calculate Block Surface Height
/////////////////////////////////
if(ExpandedArraySize > 1)
{
uint32_t Height0, Height1, Mip0BlockHeight, Slice0Delta = 0;
Height0 = __GMM_EXPAND_HEIGHT(this, Height, VAlign, pTexInfo);
Height1 = __GMM_EXPAND_HEIGHT(this, Height >> 1, VAlign, pTexInfo);
Mip0BlockHeight = BlockHeight = (pTexInfo->MaxLod > 0) ?
Height0 + Height1 + 12 * VAlign :
Height0;
BlockHeight -= (pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips) ? Height0 : 0;
if(pTexInfo->Flags.Gpu.S3dDx && pGmmLibContext->GetSkuTable().FtrDisplayEngineS3d)
{
BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
}
// QPitch for compressed surface must be multiple of BlockHeight and 4...
if(Compress && (CompressHeight % 4))
{
uint32_t LCM = CompressHeight * ((CompressHeight % 2) ? 4 : 2);
BlockHeight = GFX_ALIGN_NP2(BlockHeight, LCM);
Mip0BlockHeight = GFX_ALIGN_NP2(Mip0BlockHeight, LCM);
}
// Gen8 QPitch programming refers to the logical view, not physical.
pTexInfo->Alignment.QPitch = BlockHeight;
if(Compress)
{
BlockHeight /= CompressHeight;
Mip0BlockHeight /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
BlockHeight /= 2;
}
else if(pTexInfo->Flags.Gpu.CCS)
{
if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
BlockHeight /= 32;
}
else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
{
BlockHeight /= 16;
}
}
Slice0Delta = (pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips) ? (Mip0BlockHeight - BlockHeight) : 0;
BlockHeight *= ExpandedArraySize;
BlockHeight += Slice0Delta;
}
else
{
pTexInfo->Alignment.QPitch = 0;
BlockHeight = Get2DMipMapHeight(pTexInfo);
}
///////////////////////////////////
// Calculate Pitch
///////////////////////////////////
AlignedWidth = __GMM_EXPAND_WIDTH(this, Width, HAlign, pTexInfo);
// Calculate special pitch case of small dimensions where LOD1 + LOD2 widths
// are greater than LOD0. e.g. dimensions 4x4 and MinPitch == 1
if(pTexInfo->MaxLod >= 2)
{
uint32_t AlignedWidthLod1, AlignedWidthLod2;
AlignedWidthLod1 = __GMM_EXPAND_WIDTH(this, Width >> 1, HAlign, pTexInfo);
AlignedWidthLod2 = __GMM_EXPAND_WIDTH(this, Width >> 2, HAlign, pTexInfo);
if((pGmmLibContext->GetWaTable().WaAstcCorruptionForOddCompressedBlockSizeX || pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips) && pPlatform->FormatTable[pTexInfo->Format].ASTC && CompressWidth == 5)
{
uint32_t Width1 = (Width == 1) ? 1 : (Width >> 1);
uint32_t Modulo10 = Width1 % 10;
if(Modulo10 >= 1 && Modulo10 <= CompressWidth)
{
AlignedWidthLod2 += 3 * CompressWidth;
}
}
AlignedWidth = GFX_MAX(AlignedWidth, AlignedWidthLod1 + AlignedWidthLod2);
}
if(Compress)
{
AlignedWidth /= CompressWidth;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
AlignedWidth *= 2;
}
else if(pTexInfo->Flags.Gpu.CCS)
{
if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
switch(pTexInfo->BitsPerPixel)
{
case 32:
AlignedWidth /= 8;
break;
case 64:
AlignedWidth /= 4;
break;
case 128:
AlignedWidth /= 2;
break;
default:
__GMM_ASSERT(0);
}
}
else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
{
switch(pTexInfo->BitsPerPixel)
{
case 32:
AlignedWidth /= 16;
break;
case 64:
AlignedWidth /= 8;
break;
case 128:
AlignedWidth /= 4;
break;
default:
__GMM_ASSERT(0);
}
}
}
else if(pTexInfo->Flags.Gpu.ColorSeparation)
{
AlignedWidth *= pTexInfo->ArraySize;
__GMM_ASSERT(0 == (AlignedWidth % GMM_COLOR_SEPARATION_WIDTH_DIVISION));
AlignedWidth /= GMM_COLOR_SEPARATION_WIDTH_DIVISION;
}
else if(pTexInfo->Flags.Gpu.ColorSeparationRGBX)
{
AlignedWidth *= pTexInfo->ArraySize;
__GMM_ASSERT(0 == (AlignedWidth % GMM_COLOR_SEPARATION_RGBX_WIDTH_DIVISION));
AlignedWidth /= GMM_COLOR_SEPARATION_RGBX_WIDTH_DIVISION;
}
// Default pitch
Pitch = AlignedWidth * BitsPerPixel >> 3;
// Make sure the pitch satisfy linear min pitch requirment
Pitch = GFX_MAX(Pitch, pRestrictions->MinPitch);
// Make sure pitch satisfy alignment restriction
Pitch = GFX_ALIGN(Pitch, pRestrictions->PitchAlignment);
////////////////////
// Adjust for Tiling
////////////////////
if(GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]))
{
Pitch = GFX_ALIGN(Pitch, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileWidth);
BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
// If Tiled Resource or Undefined64KBSwizzle resource, align to 64KB tile size
if((pTexInfo->Flags.Gpu.TiledResource || pTexInfo->Flags.Info.Undefined64KBSwizzle) &&
(pTexInfo->Flags.Info.TiledY))
{
uint32_t ColFactor = 0, RowFactor = 0;
uint32_t TRTileWidth = 0, TRTileHeight = 0;
GmmGetD3DToHwTileConversion(pTexInfo, &ColFactor, &RowFactor);
TRTileWidth = pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileWidth * ColFactor;
TRTileHeight = pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight * RowFactor;
Pitch = GFX_ALIGN(Pitch, TRTileWidth);
BlockHeight = GFX_ALIGN(BlockHeight, TRTileHeight);
}
}
GMM_ASSERTDPF(pTexInfo->Flags.Info.LayoutBelow || !pTexInfo->Flags.Info.LayoutRight, "MIPLAYOUT_RIGHT not supported after Gen6!");
pTexInfo->Flags.Info.LayoutBelow = 1;
pTexInfo->Flags.Info.LayoutRight = 0;
// If a texture is YUV packed, 96, or 48 bpp then one row plus 16 bytes of
// padding needs to be added. Since this will create a none pitch aligned
// surface the padding is aligned to the next row
if(GmmIsYUVPacked(pTexInfo->Format) ||
(pTexInfo->BitsPerPixel == GMM_BITS(96)) ||
(pTexInfo->BitsPerPixel == GMM_BITS(48)))
{
BlockHeight += GMM_SCANLINES(1) + GFX_CEIL_DIV(GMM_BYTES(16), Pitch);
}
// Align height to even row to cover for HW over-fetch
BlockHeight = GFX_ALIGN(BlockHeight, __GMM_EVEN_ROW);
if((Status = // <-- Note assignment.
FillTexPitchAndSize(
pTexInfo, Pitch, BlockHeight, pRestrictions)) == GMM_SUCCESS)
{
Fill2DTexOffsetAddress(pTexInfo);
// Init to no-packed mips. It'll be initialized when app calls to get packed
// mips. Calculate packed mips here if there's a chance apps won't call to
// get packed mips.
pTexInfo->Alignment.PackedMipStartLod = GMM_TILED_RESOURCE_NO_PACKED_MIPS;
}
if(pTexInfo->Flags.Wa.CHVAstcSkipVirtualMips)
{
uint32_t i = 0;
uint64_t SkipMip0Tiles = 0;
SkipMip0Tiles = pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[1] /
(pTexInfo->Pitch * pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight);
SkipMip0Tiles *= pTexInfo->Pitch * pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileHeight;
pTexInfo->Size -= SkipMip0Tiles;
for(i = 0; i <= pTexInfo->MaxLod; i++)
{
pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[i] -= SkipMip0Tiles;
}
}
GMM_DPF_EXIT;
return (Status);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates the address offset for each mip map of 2D texture and store them into
/// the GMM_TEXTURE_INFO for surf state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmGen8TextureCalc::Fill2DTexOffsetAddress(GMM_TEXTURE_INFO *pTexInfo)
{
uint32_t i;
GMM_DPF_ENTER;
// QPitch: Array Element-to-Element, or Cube Face-to-Face Pitch...
if((pTexInfo->ArraySize <= 1) &&
(pTexInfo->Type != RESOURCE_CUBE) &&
!(pTexInfo->Flags.Gpu.ColorSeparation ||
pTexInfo->Flags.Gpu.ColorSeparationRGBX))
{
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender = 0;
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock = 0;
}
else
{
uint32_t ArrayQPitch;
uint32_t CompressHeight, CompressWidth, CompressDepth;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
ArrayQPitch = pTexInfo->Alignment.QPitch;
if(GmmIsCompressed(pGmmLibContext, pTexInfo->Format))
{
ArrayQPitch /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
ArrayQPitch /= 2;
}
else if(pTexInfo->Flags.Gpu.CCS)
{
if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
ArrayQPitch /= 32;
}
else if(pTexInfo->Flags.Gpu.__NonMsaaTileXCcs)
{
ArrayQPitch /= 16;
}
}
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender = ArrayQPitch * pTexInfo->Pitch;
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock = ArrayQPitch * pTexInfo->Pitch;
}
for(i = 0; i <= pTexInfo->MaxLod; i++)
{
pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[i] = Get2DTexOffsetAddressPerMip(pTexInfo, i);
}
GMM_DPF_EXIT;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Allocates the 1D mip layout for surface state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: ptr to surface alignment and size restrictions
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen8TextureCalc::FillTex1D(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
return FillTex2D(pTexInfo, pRestrictions);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates the cube layout for surface state programming.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO,
/// @param[in] pRestrictions: ptr to surface alignment and size restrictions
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen8TextureCalc::FillTexCube(GMM_TEXTURE_INFO * pTexInfo,
__GMM_BUFFER_TYPE *pRestrictions)
{
return FillTex2D(pTexInfo, pRestrictions);
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function does any special-case conversion from client-provided pseudo creation
/// parameters to actual parameters for CCS.
///
/// @param[in] pTexInfo: Reference to ::GMM_TEXTURE_INFO
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GMM_STDCALL GmmLib::GmmGen8TextureCalc::MSAACCSUsage(GMM_TEXTURE_INFO *pTexInfo)
{
GMM_STATUS Status = GMM_SUCCESS;
if(pTexInfo->MSAA.NumSamples > 1) // CCS for MSAA Compression
{
Status = MSAACompression(pTexInfo);
}
else // Non-MSAA CCS Use (i.e. Render Target Fast Clear)
{
if(!pTexInfo->Flags.Info.TiledW &&
((!pTexInfo->Flags.Info.Linear) ||
(GMM_IS_4KB_TILE(pTexInfo->Flags) || GMM_IS_64KB_TILE(pTexInfo->Flags) ||
(pTexInfo->Type == RESOURCE_BUFFER && pTexInfo->Flags.Info.Linear))) && //!Yf - deprecate Yf
((pTexInfo->BitsPerPixel == 32) ||
(pTexInfo->BitsPerPixel == 64) ||
(pTexInfo->BitsPerPixel == 128)))
{
// For non-MSAA CCS usage, the four tables of
// requirements:
// (1) RT Alignment (GMM Don't Care: Occurs Naturally)
// (2) ClearRect Alignment
// (3) ClearRect Scaling (GMM Don't Care: GHAL3D Matter)
// (4) Non-MSAA CCS Sizing
// Gen8+:
// Since mip-mapped and arrayed surfaces are supported, we
// deal with alignment later at per mip level. Here, we set
// tiling type only. TileX is not supported on Gen9+.
// Pre-Gen8:
// (!) For all the above, there are separate entries for
// 32/64/128bpp--and then deals with PIXEL widths--Here,
// though, we will unify by considering 8bpp table entries
// (unlisted--i.e. do the math)--and deal with BYTE widths.
// (1) RT Alignment -- The surface width and height don't
// need to be padded to RT CL granularity. On HSW, all tiled
// RT's will have appropriate alignment (given 4KB surface
// base and no mip-map support) and appropriate padding
// (due to tile padding). On BDW+, GMM uses H/VALIGN that
// will guarantee the MCS RT alignment for all subresources.
// (2) ClearRect Alignment -- I.e. FastClears must be done
// with certain granularity:
// TileY: 512 Bytes x 128 Lines
// TileX: 1024 Bytes x 64 Lines
// So a CCS must be sized to match that granularity (though
// the RT itself need not be fully padded to that
// granularity to use FastClear).
// (4) Non-MSAA CCS Sizing -- CCS sizing is based on the
// size of the FastClear (with granularity padding) for the
// paired RT. CCS's (byte widths and heights) are scaled
// down from their RT's by:
// TileY: 32 x 32
// TileX: 64 x 16
// ### Example #############################################
// RT: 800x600, 32bpp, TileY
// 8bpp: 3200x600
// FastClear: 3584x640 (for TileY FastClear Granularity of 512x128)
// CCS: 112x20 (for TileY RT:CCS Sizing Downscale of 32x32)
pTexInfo->Flags.Gpu.__NonMsaaTileYCcs = pTexInfo->Flags.Info.TiledY || pTexInfo->Flags.Info.TiledYf || pTexInfo->Flags.Info.TiledYs;
pTexInfo->Flags.Gpu.__NonMsaaTileXCcs = pTexInfo->Flags.Info.TiledX;
}
else
{
GMM_ASSERTDPF(0, "Illegal CCS creation parameters!");
Status = GMM_ERROR;
}
}
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,828 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// This function calculates the (X,Y) address of each given plane. X is in bytes
/// and Y is in scanlines.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmTextureCalc::FillPlanarOffsetAddress(GMM_TEXTURE_INFO *pTexInfo)
{
GMM_GFX_SIZE_T *pUOffsetX, *pUOffsetY;
GMM_GFX_SIZE_T *pVOffsetX, *pVOffsetY;
uint32_t YHeight = 0, VHeight = 0;
bool UVPacked = false;
uint32_t Height;
uint32_t WidthBytesPhysical = GFX_ULONG_CAST(pTexInfo->BaseWidth) * pTexInfo->BitsPerPixel >> 3;
#define SWAP_UV() \
{ \
GMM_GFX_SIZE_T *pTemp; \
\
pTemp = pUOffsetX; \
pUOffsetX = pVOffsetX; \
pVOffsetX = pTemp; \
\
pTemp = pUOffsetY; \
pUOffsetY = pVOffsetY; \
pVOffsetY = pTemp; \
}
__GMM_ASSERTPTR(pTexInfo, VOIDRETURN);
__GMM_ASSERTPTR(((pTexInfo->TileMode < GMM_TILE_MODES) && (pTexInfo->TileMode >= TILE_NONE)), VOIDRETURN);
GMM_DPF_ENTER;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
// GMM_PLANE_Y always at (0, 0)...
pTexInfo->OffsetInfo.Plane.X[GMM_PLANE_Y] = 0;
pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_Y] = 0;
Height = pTexInfo->BaseHeight;
if(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
Height = __GMM_EXPAND_HEIGHT(this, Height, pTexInfo->Alignment.VAlign, pTexInfo);
Height = ScaleTextureHeight(pTexInfo, Height);
if(pTexInfo->Flags.Gpu.UnifiedAuxSurface)
{
pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_Y] = 0;
}
}
// GMM_PLANE_U/V Planes...
pUOffsetX = &pTexInfo->OffsetInfo.Plane.X[GMM_PLANE_U];
pUOffsetY = &pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_U];
pVOffsetX = &pTexInfo->OffsetInfo.Plane.X[GMM_PLANE_V];
pVOffsetY = &pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_V];
switch(pTexInfo->Format)
{
case GMM_FORMAT_IMC1:
SWAP_UV(); // IMC1 = IMC3 with Swapped U/V
case GMM_FORMAT_IMC3:
case GMM_FORMAT_MFX_JPEG_YUV420: // Same as IMC3.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUU
// UUUU
// VVVV
// VVVV
case GMM_FORMAT_MFX_JPEG_YUV422V: // Similar to IMC3 but U/V are full width.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUUUUU
// UUUUUUUU
// VVVVVVVV
// VVVVVVVV
{
*pUOffsetX = 0;
YHeight = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pUOffsetY = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetX = 0;
VHeight = GFX_ALIGN(GFX_CEIL_DIV(pTexInfo->BaseHeight, 2), GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetY =
GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT) +
GFX_ALIGN(GFX_CEIL_DIV(pTexInfo->BaseHeight, 2), GMM_IMCx_PLANE_ROW_ALIGNMENT);
break;
}
case GMM_FORMAT_MFX_JPEG_YUV411R_TYPE: //Similar to IMC3 but U/V are quarther height and full width.
//YYYYYYYY
//YYYYYYYY
//YYYYYYYY
//YYYYYYYY
//UUUUUUUU
//VVVVVVVV
{
*pUOffsetX = 0;
YHeight = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pUOffsetY = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetX = 0;
VHeight = GFX_ALIGN(GFX_CEIL_DIV(pTexInfo->BaseHeight, 4), GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetY =
GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT) +
GFX_ALIGN(GFX_CEIL_DIV(pTexInfo->BaseHeight, 4), GMM_IMCx_PLANE_ROW_ALIGNMENT);
break;
}
case GMM_FORMAT_MFX_JPEG_YUV411: // Similar to IMC3 but U/V are quarter width and full height.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UU
// UU
// UU
// UU
// VV
// VV
// VV
// VV
case GMM_FORMAT_MFX_JPEG_YUV422H: // Similar to IMC3 but U/V are full height.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUU
// UUUU
// UUUU
// UUUU
// VVVV
// VVVV
// VVVV
// VVVV
case GMM_FORMAT_MFX_JPEG_YUV444: // Similar to IMC3 but U/V are full size.
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUUUUU
// UUUUUUUU
// UUUUUUUU
// UUUUUUUU
// VVVVVVVV
// VVVVVVVV
// VVVVVVVV
// VVVVVVVV
{
*pUOffsetX = 0;
YHeight = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pUOffsetY = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetX = 0;
VHeight = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetY = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT) * 2;
break;
}
case GMM_FORMAT_BGRP:
case GMM_FORMAT_RGBP:
{
//For RGBP linear Tile keep resource Offset non aligned and for other Tile format to be 16-bit aligned
if(pTexInfo->Flags.Info.Linear)
{
*pUOffsetX = 0;
YHeight = pTexInfo->BaseHeight;
*pUOffsetY = pTexInfo->BaseHeight;
*pVOffsetX = 0;
VHeight = pTexInfo->BaseHeight;
*pVOffsetY = (GMM_GFX_SIZE_T)pTexInfo->BaseHeight * 2;
}
else // Tiled
{
*pUOffsetX = 0;
YHeight = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pUOffsetY = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetX = 0;
VHeight = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetY = (GMM_GFX_SIZE_T)GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT) * 2;
}
break;
}
case GMM_FORMAT_IMC2:
SWAP_UV(); // IMC2 = IMC4 with Swapped U/V
case GMM_FORMAT_IMC4:
{
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUVVVV
// UUUUVVVV
__GMM_ASSERT((pTexInfo->Pitch & 1) == 0);
*pUOffsetX = 0;
YHeight = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pUOffsetY = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
*pVOffsetX = pTexInfo->Pitch / 2;
VHeight = GFX_CEIL_DIV(YHeight, 2);
*pVOffsetY = GFX_ALIGN(pTexInfo->BaseHeight, GMM_IMCx_PLANE_ROW_ALIGNMENT);
// Not technically UV packed but sizing works out the same
UVPacked = true;
break;
}
case GMM_FORMAT_I420: // I420 = IYUV
case GMM_FORMAT_IYUV:
SWAP_UV(); // I420/IYUV = YV12 with Swapped U/V
case GMM_FORMAT_YV12:
case GMM_FORMAT_YVU9:
{
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// VVVVVV.. <-- V and U planes follow the Y plane, as linear
// ..UUUUUU arrays--without respect to pitch.
uint32_t YSize, YVSizeRShift, VSize, UOffset;
uint32_t YSizeForUVPurposes, YSizeForUVPurposesDimensionalAlignment;
YSize = GFX_ULONG_CAST(pTexInfo->Pitch) * pTexInfo->BaseHeight;
// YVU9 has one U/V pixel for each 4x4 Y block.
// The others have one U/V pixel for each 2x2 Y block.
// YVU9 has a Y:V size ratio of 16 (4x4 --> 1).
// The others have a ratio of 4 (2x2 --> 1).
YVSizeRShift = (pTexInfo->Format != GMM_FORMAT_YVU9) ? 2 : 4;
// If a Y plane isn't fully-aligned to its Y-->U/V block size, the
// extra/unaligned Y pixels still need corresponding U/V pixels--So
// for the purpose of computing the UVSize, we must consider a
// dimensionally "rounded-up" YSize. (E.g. a 13x5 YVU9 Y plane would
// require 4x2 U/V planes--the same UVSize as a fully-aligned 16x8 Y.)
YSizeForUVPurposesDimensionalAlignment = (pTexInfo->Format != GMM_FORMAT_YVU9) ? 2 : 4;
YSizeForUVPurposes =
GFX_ALIGN(GFX_ULONG_CAST(pTexInfo->Pitch), YSizeForUVPurposesDimensionalAlignment) *
GFX_ALIGN(pTexInfo->BaseHeight, YSizeForUVPurposesDimensionalAlignment);
VSize = (YSizeForUVPurposes >> YVSizeRShift);
UOffset = YSize + VSize;
*pVOffsetX = 0;
*pVOffsetY = pTexInfo->BaseHeight;
*pUOffsetX = UOffset % pTexInfo->Pitch;
*pUOffsetY = UOffset / pTexInfo->Pitch;
YHeight = GFX_CEIL_DIV(YSize + 2 * VSize, WidthBytesPhysical);
break;
}
case GMM_FORMAT_NV12:
case GMM_FORMAT_NV21:
case GMM_FORMAT_NV11:
case GMM_FORMAT_P010:
case GMM_FORMAT_P012:
case GMM_FORMAT_P016:
case GMM_FORMAT_P208:
case GMM_FORMAT_P216:
{
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// [UV-Packing]
*pUOffsetX = *pVOffsetX = 0;
YHeight = GFX_ALIGN(Height, __GMM_EVEN_ROW);
*pUOffsetY = *pVOffsetY = YHeight;
if((pTexInfo->Format == GMM_FORMAT_NV12) ||
(pTexInfo->Format == GMM_FORMAT_NV21) ||
(pTexInfo->Format == GMM_FORMAT_P010) ||
(pTexInfo->Format == GMM_FORMAT_P012) ||
(pTexInfo->Format == GMM_FORMAT_P016))
{
VHeight = GFX_CEIL_DIV(Height, 2);
}
else
{
VHeight = YHeight; // U/V plane is same as Y
}
UVPacked = true;
break;
}
default:
{
GMM_ASSERTDPF(0, "Unknown Video Format U\n");
break;
}
}
pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_Y] = YHeight;
if(pTexInfo->OffsetInfo.Plane.NoOfPlanes == 2)
{
pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U] = VHeight;
}
else if(pTexInfo->OffsetInfo.Plane.NoOfPlanes == 3)
{
pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_U] =
pTexInfo->OffsetInfo.Plane.UnAligned.Height[GMM_PLANE_V] = VHeight;
}
if(GMM_IS_TILED(pPlatform->TileInfo[pTexInfo->TileMode]) || pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
GMM_GFX_SIZE_T TileHeight = pGmmLibContext->GetPlatformInfo().TileInfo[pTexInfo->TileMode].LogicalTileHeight;
GMM_GFX_SIZE_T TileWidth = pGmmLibContext->GetPlatformInfo().TileInfo[pTexInfo->TileMode].LogicalTileWidth;
*pUOffsetX = GFX_ALIGN(*pUOffsetX, TileWidth);
*pUOffsetY = GFX_ALIGN(*pUOffsetY, TileHeight);
*pVOffsetX = GFX_ALIGN(*pVOffsetX, TileWidth);
*pVOffsetY = UVPacked ?
GFX_ALIGN(*pVOffsetY, TileHeight) :
GFX_ALIGN(YHeight, TileHeight) + GFX_ALIGN(VHeight, TileHeight);
if(pTexInfo->Flags.Gpu.UnifiedAuxSurface && pTexInfo->Flags.Gpu.__NonMsaaTileYCcs)
{
*pUOffsetY += pTexInfo->OffsetInfo.Plane.Y[GMM_PLANE_Y];
*pVOffsetY = *pUOffsetY;
}
}
//Special case LKF MMC compressed surfaces
if(pTexInfo->Flags.Gpu.MMC &&
pTexInfo->Flags.Gpu.UnifiedAuxSurface &&
GMM_IS_4KB_TILE(pTexInfo->Flags))
{
GMM_GFX_SIZE_T TileHeight = pGmmLibContext->GetPlatformInfo().TileInfo[pTexInfo->TileMode].LogicalTileHeight;
GMM_GFX_SIZE_T TileWidth = pGmmLibContext->GetPlatformInfo().TileInfo[pTexInfo->TileMode].LogicalTileWidth;
*pUOffsetX = GFX_ALIGN(*pUOffsetX, TileWidth);
*pUOffsetY = GFX_ALIGN(*pUOffsetY, TileHeight);
*pVOffsetX = GFX_ALIGN(*pVOffsetX, TileWidth);
*pVOffsetY = GFX_ALIGN(*pVOffsetY, TileHeight);
}
GMM_DPF_EXIT;
#undef SWAP_UV
}
/////////////////////////////////////////////////////////////////////////////////////
/// Sibling function of GmmLib::GmmTextureCalc::ExpandWidth. it returns the given
/// Width, as appropriately scaled by the MSAA NumSamples parameter and aligned to the
/// given UnitAlignment.
///
/// @param[in] Height: Height of the surface
/// @param[in] UnitAlignment: Unit alignment factor
/// @param[in] NumSamples: No of MSAA samples
///
/// @return scaled height
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmTextureCalc::ExpandHeight(uint32_t Height, uint32_t UnitAlignment, uint32_t NumSamples)
{
// Implemented as separate function (instead of as a single function with a
// Width/Height parameter) so both functions can be later implemented without
// branches, if need be.
return (
GmmLib::GmmTextureCalc::ExpandWidth(
Height, UnitAlignment,
(NumSamples == 2) ? 1 : // MSAA_2X: No height adjustment
((NumSamples == 8) ? 4 : NumSamples))); // <-- MSAA_8X:Height = MSAA_4X:Height.
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function returns the given Width, as appropriately scaled by the MSAA
/// NumSamples parameter and aligned to the given UnitAlignment.
///
/// @param[in] Width: Height of the surface
/// @param[in] UnitAlignment: Unit alignment factor
/// @param[in] NumSamples: No of MSAA samples
///
/// @return scaled width
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmTextureCalc::ExpandWidth(uint32_t Width, uint32_t UnitAlignment, uint32_t NumSamples)
{
uint32_t ExpandedWidth;
switch(NumSamples)
{
case 1:
ExpandedWidth = Width;
break;
case 2: // Same as 4x...
case 4:
ExpandedWidth = GFX_CEIL_DIV(GFX_MAX(Width, 1), 2) * 4;
break;
case 8: // Same as 16x...
case 16:
ExpandedWidth = GFX_CEIL_DIV(GFX_MAX(Width, 1), 2) * 8;
break;
default:
ExpandedWidth = Width;
__GMM_ASSERT(0);
}
ExpandedWidth = GFX_MAX(ExpandedWidth, UnitAlignment);
ExpandedWidth = GFX_ALIGN_NP2(ExpandedWidth, UnitAlignment);
return (ExpandedWidth);
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function calculates Mip Tail Start LOD using max mip tail dimensions and
/// populates pTexInfo->Alignment.MipTailStartLod
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmTextureCalc::FindMipTailStartLod(GMM_TEXTURE_INFO *pTexInfo)
{
GMM_DPF_ENTER;
if(!(pTexInfo->Flags.Info.TiledYf || GMM_IS_64KB_TILE(pTexInfo->Flags)) ||
(pTexInfo->MaxLod == 0) ||
(pTexInfo->Flags.Wa.DisablePackedMipTail))
{
// HW never ignores MipTailStartLod for Yf/Ys surfaces. If we do not
// want a mip tail, we set MipTailStartLod to be greater than MaxLod.
pTexInfo->Alignment.MipTailStartLod = GMM_TILED_RESOURCE_NO_MIP_TAIL;
}
else
{
uint32_t MipDepth, MipHeight, MipWidth, CompressWidth, CompressHeight, CompressDepth;
uint32_t Level = 0;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
MipDepth = pTexInfo->Depth;
MipHeight = pTexInfo->BaseHeight;
MipWidth = GFX_ULONG_CAST(pTexInfo->BaseWidth);
//if compressed texture format, use compressed height, width
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
if(GmmIsCompressed(pGmmLibContext, pTexInfo->Format))
{
MipWidth = GFX_CEIL_DIV(MipWidth, CompressWidth);
MipHeight = GFX_CEIL_DIV(MipHeight, CompressHeight);
MipDepth = GFX_CEIL_DIV(MipDepth, CompressDepth);
}
while((Level < pTexInfo->MaxLod) &&
(((pTexInfo->Type == RESOURCE_1D) &&
!(MipWidth <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartWidth)) ||
(((pTexInfo->Type == RESOURCE_2D) || (pTexInfo->Type == RESOURCE_CUBE)) &&
!((MipWidth <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartWidth) &&
(MipHeight <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartHeight))) ||
((pTexInfo->Type == RESOURCE_3D) &&
!((MipWidth <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartWidth) &&
(MipHeight <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartHeight) &&
(MipDepth <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartDepth)))))
{
Level++;
MipWidth = GFX_ULONG_CAST(GmmTexGetMipWidth(pTexInfo, Level));
MipHeight = GmmTexGetMipHeight(pTexInfo, Level);
MipDepth = GmmTexGetMipDepth(pTexInfo, Level);
MipWidth = GFX_CEIL_DIV(MipWidth, CompressWidth);
MipHeight = GFX_CEIL_DIV(MipHeight, CompressHeight);
MipDepth = GFX_CEIL_DIV(MipDepth, CompressDepth);
}
if(((pTexInfo->Type == RESOURCE_1D) &&
(MipWidth <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartWidth)) ||
(((pTexInfo->Type == RESOURCE_2D) || (pTexInfo->Type == RESOURCE_CUBE)) &&
((MipWidth <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartWidth) &&
(MipHeight <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartHeight))) ||
((pTexInfo->Type == RESOURCE_3D) &&
((MipWidth <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartWidth) &&
(MipHeight <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartHeight) &&
(MipDepth <= pPlatform->TileInfo[pTexInfo->TileMode].MaxMipTailStartDepth))))
{
pTexInfo->Alignment.MipTailStartLod = Level;
}
else
{
pTexInfo->Alignment.MipTailStartLod = GMM_TILED_RESOURCE_NO_MIP_TAIL;
}
}
GMM_DPF_EXIT;
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function returns the height, width and depth of the compression block for a
/// given surface format.
///
/// @param[in] Format: ::GMM_RESOURCE_FORMAT
/// @param[in] pWidth: populates Width
/// @param[in] pHeight: populates Height
/// @param[in] pDepth: populates Depth
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmTextureCalc::GetCompressionBlockDimensions(GMM_RESOURCE_FORMAT Format,
uint32_t * pWidth,
uint32_t * pHeight,
uint32_t * pDepth)
{
GMM_DPF_ENTER;
__GMM_ASSERT(pWidth && pHeight && pDepth);
if(pWidth && pHeight && pDepth)
{
if((Format > GMM_FORMAT_INVALID) && (Format < GMM_RESOURCE_FORMATS))
{
*pWidth = pGmmLibContext->GetPlatformInfo().FormatTable[Format].Element.Width;
*pHeight = pGmmLibContext->GetPlatformInfo().FormatTable[Format].Element.Height;
*pDepth = pGmmLibContext->GetPlatformInfo().FormatTable[Format].Element.Depth;
}
else
{
*pWidth = 1;
*pHeight = 1;
*pDepth = 1;
}
}
GMM_DPF_EXIT;
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function Convert from d3d tile (64KB) to h/w tile
///
/// @param[in] pTexInfo: ::GMM_TEXTURE_INFO
/// @param[in/out] pColFactor: populates Width
/// @param[in/out] pRowFactor: populates Height
/// @param[out] true on Success else false
///
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::GmmTextureCalc::GmmGetD3DToHwTileConversion(GMM_TEXTURE_INFO *pTexInfo,
uint32_t * pColFactor,
uint32_t * pRowFactor)
{
uint32_t i = 0;
uint32_t Bpp = pTexInfo->BitsPerPixel;
// check for unsupported bpp
if(!(Bpp == 8 || Bpp == 16 || Bpp == 32 || Bpp == 64 || Bpp == 128))
{
__GMM_ASSERT(false);
goto EXIT_ERROR;
}
// for TileYS, no conversion
if(GMM_IS_64KB_TILE(pTexInfo->Flags) || pTexInfo->Flags.Info.Linear)
{
*pColFactor = 1;
*pRowFactor = 1;
}
else if(GMM_IS_4KB_TILE(pTexInfo->Flags))
{
// Logic for non-MSAA
{
// Bpp = 8 => i = 0 , Bpp = 16 => i = 1, ...
// Log2(Bpp = 8) = 3 => i = Log2(8) - 3.
i = __GmmLog2(Bpp) - 3;
*pColFactor = __GmmTileYConversionTable[i][0];
*pRowFactor = __GmmTileYConversionTable[i][1];
}
// Logic for MSAA
if(pTexInfo->MSAA.NumSamples > 1)
{
// For MSAA, the DirectX tile dimensions change, using the table __GmmMSAAConversion.
uint32_t W = __GmmMSAAConversion[__GmmLog2(pTexInfo->MSAA.NumSamples)][0];
uint32_t H = __GmmMSAAConversion[__GmmLog2(pTexInfo->MSAA.NumSamples)][1];
// For the new DirectX tile dimensions the new Col and Row conversion factors are:
*pColFactor /= W;
*pRowFactor /= H;
}
}
else
{
// unsupported format.
__GMM_ASSERT(false);
goto EXIT_ERROR;
}
return true;
EXIT_ERROR:
*pColFactor = 0;
*pRowFactor = 0;
return false;
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function redescribes WidthBytesPhysical of main surface as per UV plane bpp and tilemode
///
/// @return ::bool
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::GmmTextureCalc::RedescribeTexturePlanes(GMM_TEXTURE_INFO *pTexInfo, uint32_t *pWidthBytesPhysical)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_TEXTURE_INFO TexInfoUVPlane;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
__GMM_ASSERT(pTexInfo);
__GMM_ASSERT(pTexInfo->Flags.Info.RedecribedPlanes);
__GMM_ASSERT(pWidthBytesPhysical);
TexInfoUVPlane = *pTexInfo;
#ifdef _WIN32
memcpy_s(&TexInfoUVPlane, sizeof(GMM_TEXTURE_INFO), pTexInfo, sizeof(GMM_TEXTURE_INFO));
#else
memcpy(&TexInfoUVPlane, pTexInfo, sizeof(GMM_TEXTURE_INFO));
#endif // _WIN32
if(GmmIsUVPacked(pTexInfo->Format))
{
// UV packed resources must have two seperate
// tiling modes per plane, due to the packed
// UV plane having twice the bits per pixel
// as the Y plane.
switch(pTexInfo->Format)
{
case GMM_FORMAT_NV12:
case GMM_FORMAT_NV21:
case GMM_FORMAT_P208:
TexInfoUVPlane.BitsPerPixel = 16; // Redescribe bpp to 16 from 8
break;
case GMM_FORMAT_P010:
case GMM_FORMAT_P012:
case GMM_FORMAT_P016:
case GMM_FORMAT_P216:
TexInfoUVPlane.BitsPerPixel = 32;
break;
default:
GMM_ASSERTDPF(0, "Unsupported format/pixel size combo!");
Status = GMM_INVALIDPARAM;
goto ERROR_CASE;
break;
}
}
else
{
// Non-UV packed surfaces, TileMode and bpp of each plane is same as that of pTexInfo
}
SetTileMode(&TexInfoUVPlane);
*pWidthBytesPhysical = GFX_ALIGN(*pWidthBytesPhysical, pPlatform->TileInfo[TexInfoUVPlane.TileMode].LogicalTileWidth);
ERROR_CASE:
return (Status == GMM_SUCCESS) ? true : false;
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function returns per plane redescribed parameters (pRedescribedTexInfo: fmt, tilemode,bpp, width, height, size) when main surface pTexInfo is passed
///
/// @return ::bool
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::GmmTextureCalc::GetRedescribedPlaneParams(GMM_TEXTURE_INFO *pTexInfo, GMM_YUV_PLANE PlaneType, GMM_TEXTURE_INFO *pRedescribedTexInfo)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_TEXTURE_INFO TexInfoUVPlane;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
__GMM_ASSERT(pTexInfo);
__GMM_ASSERT(pTexInfo->Flags.Info.RedecribedPlanes);
__GMM_ASSERT(pRedescribedTexInfo);
*pRedescribedTexInfo = *pTexInfo;
pRedescribedTexInfo->Flags.Info.RedecribedPlanes = 0;
#ifdef _WIN32
memcpy_s(&TexInfoUVPlane, sizeof(GMM_TEXTURE_INFO), pTexInfo, sizeof(GMM_TEXTURE_INFO));
#else
memcpy(&TexInfoUVPlane, pTexInfo, sizeof(GMM_TEXTURE_INFO));
#endif // _WIN32
if(GmmIsUVPacked(pTexInfo->Format))
{
// UV packed resources must have two seperate
// tiling modes per plane, due to the packed
// UV plane having twice the bits per pixel
// as the Y plane.
if((PlaneType == GMM_PLANE_U) || (PlaneType == GMM_PLANE_V))
{
switch(pTexInfo->Format)
{
// GMM_FORMAT_NV11 : linear format, no tiling supported, hence no redescription supported
case GMM_FORMAT_NV12:
case GMM_FORMAT_NV21:
pRedescribedTexInfo->BitsPerPixel = 16;
pRedescribedTexInfo->BaseWidth = GFX_CEIL_DIV(pTexInfo->BaseWidth, 2);
pRedescribedTexInfo->BaseHeight = GFX_CEIL_DIV(pTexInfo->BaseHeight, 2);
break;
case GMM_FORMAT_P208:
pRedescribedTexInfo->BitsPerPixel = 16;
pRedescribedTexInfo->BaseWidth = GFX_CEIL_DIV(pTexInfo->BaseWidth, 2);
// same base height as main surface
break;
case GMM_FORMAT_P010:
case GMM_FORMAT_P012:
case GMM_FORMAT_P016:
pRedescribedTexInfo->BitsPerPixel = 32;
pRedescribedTexInfo->BaseWidth = GFX_CEIL_DIV(pTexInfo->BaseWidth, 2);
pRedescribedTexInfo->BaseHeight = GFX_CEIL_DIV(pTexInfo->BaseHeight, 2);
break;
case GMM_FORMAT_P216:
pRedescribedTexInfo->BitsPerPixel = 32;
pRedescribedTexInfo->BaseWidth = GFX_CEIL_DIV(pTexInfo->BaseWidth, 2);
// same base height as main surface
break;
default:
GMM_ASSERTDPF(0, "Unsupported format/pixel size combo!");
Status = GMM_INVALIDPARAM;
goto ERROR_CASE;
break;
}
}
}
else
{
// Non-UV packed surfaces TileMode of each plane is same as that of pTexInfo
if((PlaneType == GMM_PLANE_U) || (PlaneType == GMM_PLANE_V))
{ // Non-UV packed surfaces only require the plane descriptors have proper height and width for each plane
switch(pTexInfo->Format)
{
case GMM_FORMAT_IMC1:
case GMM_FORMAT_IMC2:
case GMM_FORMAT_IMC3:
case GMM_FORMAT_IMC4:
case GMM_FORMAT_MFX_JPEG_YUV420:
pRedescribedTexInfo->BaseWidth = GFX_CEIL_DIV(pTexInfo->BaseWidth, 2);
pRedescribedTexInfo->BaseHeight = GFX_CEIL_DIV(pTexInfo->BaseHeight, 2);
break;
case GMM_FORMAT_MFX_JPEG_YUV422V:
pRedescribedTexInfo->BaseHeight = GFX_CEIL_DIV(pTexInfo->BaseHeight, 2);
break;
case GMM_FORMAT_MFX_JPEG_YUV411R_TYPE:
pRedescribedTexInfo->BaseHeight = GFX_CEIL_DIV(pTexInfo->BaseHeight, 4);
break;
case GMM_FORMAT_MFX_JPEG_YUV411:
pRedescribedTexInfo->BaseWidth = GFX_CEIL_DIV(pTexInfo->BaseWidth, 4);
break;
case GMM_FORMAT_MFX_JPEG_YUV422H:
pRedescribedTexInfo->BaseWidth = GFX_CEIL_DIV(pTexInfo->BaseWidth, 2);
break;
default:
GMM_ASSERTDPF(0, "Unsupported format/pixel size combo!");
Status = GMM_INVALIDPARAM;
goto ERROR_CASE;
break;
}
}
}
SetTileMode(pRedescribedTexInfo);
switch(pRedescribedTexInfo->BitsPerPixel)
{
case 8:
pRedescribedTexInfo->Format = GMM_FORMAT_R8_UINT;
break;
case 16:
pRedescribedTexInfo->Format = GMM_FORMAT_R16_UINT;
break;
case 32:
pRedescribedTexInfo->Format = GMM_FORMAT_R32_UINT;
break;
default:
GMM_ASSERTDPF(0, "Unsupported format/pixel size combo!");
Status = GMM_INVALIDPARAM;
goto ERROR_CASE;
break;
}
if(pTexInfo->ArraySize > 1)
{
pRedescribedTexInfo->OffsetInfo.Plane.ArrayQPitch = 0; // no longer a planar format on redescription
pRedescribedTexInfo->Alignment.QPitch = GFX_ALIGN(pRedescribedTexInfo->BaseHeight, pTexInfo->Alignment.VAlign);
pRedescribedTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender =
pRedescribedTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock = pRedescribedTexInfo->Alignment.QPitch * pTexInfo->Pitch;
pRedescribedTexInfo->Size = pRedescribedTexInfo->Alignment.QPitch * pTexInfo->Pitch * pTexInfo->ArraySize;
}
else
{
pRedescribedTexInfo->Size = (GFX_ALIGN(pRedescribedTexInfo->BaseHeight, pTexInfo->Alignment.VAlign)) * pTexInfo->Pitch;
}
ERROR_CASE:
return (Status == GMM_SUCCESS) ? true : false;
}

View File

@ -0,0 +1,574 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "External/Common/GmmInternal.h" // UMD or KMD Windows header
#include "External/Common/GmmTextureExt.h"
#include "External/Common/GmmUtil.h"
#include "External/Common/GmmInfoExt.h"
#include "External/Common/GmmInfo.h"
#include "External/Common/GmmProto.h"
#ifdef __cplusplus
#include "Internal/Common/Texture/GmmTextureCalc.h"
//---------------------------------------------------------------------------
// ExpandWidth/Height Wrappers
//
// Gen7+ MSAA (non-Depth/Stencil) render targets use array expansion instead of
// Width/Height expansion--So they pass NumSamples=1 to __GmmExpandXxx functions.
//
//---------------------------------------------------------------------------
#define __GMM_EXPAND_Xxx(ptr, Xxx, Dimension, UnitAlignment, pTexInfo) \
(ptr)->Expand##Xxx( \
(Dimension), (UnitAlignment), \
((pTexInfo)->Flags.Gpu.Depth || (pTexInfo)->Flags.Gpu.SeparateStencil) ? \
(pTexInfo)->MSAA.NumSamples : 1)
#define __GMM_EXPAND_WIDTH(ptr, __Width, UnitAlignment, pTexInfo) \
__GMM_EXPAND_Xxx(ptr, Width, __Width, UnitAlignment, pTexInfo)
#define __GMM_EXPAND_HEIGHT(ptr, __Height, UnitAlignment, pTexInfo) \
__GMM_EXPAND_Xxx(ptr, Height, __Height, UnitAlignment, pTexInfo)
//=============================================================================
//Function:
// __GmmTexFillHAlignVAlign
//
//Description:
// Stores in pTexInfo the appropriate unit aligment sizes.
//
//-----------------------------------------------------------------------------
// Gmmlib 2.0 TODO[Low] Move to Class and Inline function handling.
GMM_INLINE GMM_STATUS __GmmTexFillHAlignVAlign(GMM_TEXTURE_INFO *pTexInfo,GMM_LIB_CONTEXT* pGmmLibContext)
{
uint32_t UnitAlignWidth = 0;
uint32_t UnitAlignHeight = 0;
uint32_t UnitAlignDepth = 0;
const GMM_PLATFORM_INFO *pPlatform;
GMM_TEXTURE_CALC *pTextureCalc;
GMM_DPF_ENTER;
__GMM_ASSERTPTR(pGmmLibContext,GMM_ERROR);
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
#define SET_ALIGN_FACTOR(Xxx, Bytes) \
if(!pGmmLibContext->GetSkuTable().FtrTileY) \
{ \
UnitAlign##Xxx = \
(pTexInfo->BitsPerPixel == 128) ? Bytes/16 : \
(pTexInfo->BitsPerPixel == 64) ? Bytes/8 : \
(pTexInfo->BitsPerPixel == 32) ? Bytes/4 : \
(pTexInfo->BitsPerPixel == 16) ? Bytes/2 : Bytes ; \
\
if(!pTexInfo->Flags.Info.Linear && \
(pTexInfo->BitsPerPixel == 24 || pTexInfo->BitsPerPixel == 48 || pTexInfo->BitsPerPixel == 96)) \
{ \
UnitAlign##Xxx = 16; \
} \
else if (pTexInfo->Flags.Info.Linear && \
(pTexInfo->BitsPerPixel == 24 || pTexInfo->BitsPerPixel == 48 || pTexInfo->BitsPerPixel == 96))\
{ \
UnitAlign##Xxx = 128; \
} \
}
if (!((pTexInfo->Format > GMM_FORMAT_INVALID) &&
(pTexInfo->Format < GMM_RESOURCE_FORMATS)))
{
GMM_DPF_CRITICAL("Invalid Resource Format");
return GMM_ERROR;
}
if( !pTexInfo->Alignment.HAlign &&
!pTexInfo->Alignment.VAlign)
{
pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo,pGmmLibContext);
pTextureCalc = GMM_OVERRIDE_TEXTURE_CALC(pTexInfo,pGmmLibContext);
/// SKL TiledYf/Ys Surfaces //////////////////////////////////////////
if( ((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE) &&
(pTexInfo->Flags.Info.TiledYf || GMM_IS_64KB_TILE(pTexInfo->Flags))))
{
#define SET_ALIGN_INFO(Xxx, A1, A2, A3, A4, A5) \
UnitAlign##Xxx = \
(pTexInfo->BitsPerPixel == 128) ? A1 : \
(pTexInfo->BitsPerPixel == 64) ? A2 : \
(pTexInfo->BitsPerPixel == 32) ? A3 : \
(pTexInfo->BitsPerPixel == 16) ? A4 : A5; \
if(pTexInfo->Type == RESOURCE_1D)
{
if(pTexInfo->Flags.Info.TiledYf)
{
SET_ALIGN_INFO(Width, 256, 512, 1024, 2048, 4096);
}
else // if(pTexInfo->Flags.Info.TiledYs)
{
SET_ALIGN_INFO(Width, 4096, 8192, 16384, 32768, 65536);
}
}
else if((pTexInfo->Type == RESOURCE_2D) || (pTexInfo->Type == RESOURCE_CUBE) ||
(pTexInfo->Type == RESOURCE_PRIMARY))
{
if(pTexInfo->Flags.Info.TiledYf)
{
SET_ALIGN_INFO(Width, 16, 32, 32, 64, 64);
SET_ALIGN_INFO(Height, 16, 16, 32, 32, 64);
}
else // if(pTexInfo->Flags.Info.TiledYs)
{
SET_ALIGN_INFO(Width, 64, 128, 128, 256, 256);
SET_ALIGN_INFO(Height, 64, 64, 128, 128, 256);
}
// Only color buffer MSAA
if(pTexInfo->MSAA.NumSamples > 1 &&
!pTexInfo->Flags.Gpu.Depth &&
!pTexInfo->Flags.Gpu.SeparateStencil)
{
if(pGmmLibContext->GetSkuTable().FtrTileY)
{
switch(pTexInfo->MSAA.NumSamples)
{
case 16: UnitAlignWidth /= 4; UnitAlignHeight /= 4; break;
case 8: UnitAlignWidth /= 4; UnitAlignHeight /= 2; break;
case 4: UnitAlignWidth /= 2; UnitAlignHeight /= 2; break;
case 2: UnitAlignWidth /= 2; break;
default: __GMM_ASSERT(0);
}
}
else
{
switch (pTexInfo->MSAA.NumSamples)
{
case 4:
case 8:
case 16: UnitAlignWidth /= 2; UnitAlignHeight /= 2; break;
case 2: UnitAlignWidth /= 2; break;
default: __GMM_ASSERT(0);
}
}
}
}
else if(pTexInfo->Type == RESOURCE_3D)
{
if(pTexInfo->Flags.Info.TiledYf)
{
SET_ALIGN_INFO(Width, 4, 8, 8, 8, 16);
SET_ALIGN_INFO(Height, 8, 8, 16, 16, 16);
SET_ALIGN_INFO(Depth, 8, 8, 8, 16, 16);
}
else // if(pTexInfo->Flags.Info.TiledYs)
{
SET_ALIGN_INFO(Width, 16, 32, 32, 32, 64);
SET_ALIGN_INFO(Height, 16, 16, 32, 32, 32);
SET_ALIGN_INFO(Depth, 16, 16, 16, 32, 32);
}
}
#undef SET_ALIGN_INFO
if(GmmIsCompressed(pGmmLibContext, pTexInfo->Format))
{
uint32_t ElementWidth, ElementHeight, ElementDepth;
pTextureCalc->GetCompressionBlockDimensions(pTexInfo->Format, &ElementWidth, &ElementHeight, &ElementDepth);
UnitAlignWidth *= ElementWidth;
UnitAlignHeight *= ElementHeight;
UnitAlignDepth *= ElementDepth;
}
}
/// SKL 1D Surfaces ///////////////////////////////////////////////
else if((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE) &&
(pTexInfo->Type == RESOURCE_1D))
{
UnitAlignWidth = 64;
// Tile4/64
SET_ALIGN_FACTOR(Width, 128);
}
/// CCS ///////////////////////////////////////////////////////////
else if (pTexInfo->Flags.Gpu.CCS &&
(pTexInfo->Flags.Gpu.__NonMsaaTileYCcs || pTexInfo->Flags.Gpu.__NonMsaaTileXCcs))
{
UnitAlignWidth = pPlatform->TexAlign.CCS.Align.Width;
UnitAlignHeight = pPlatform->TexAlign.CCS.Align.Height;
ALIGNMENT UnitAlign = { UnitAlignWidth , UnitAlignHeight, UnitAlignDepth };
pGmmLibContext->GetPlatformInfoObj()->ApplyExtendedTexAlign(pTexInfo->CCSModeAlign, UnitAlign);
if (UnitAlign.Width != UnitAlignWidth ||
UnitAlign.Height != UnitAlignHeight ||
UnitAlign.Depth != UnitAlignDepth)
{
UnitAlignWidth = UnitAlign.Width;
UnitAlignHeight = UnitAlign.Height;
UnitAlignDepth = UnitAlign.Depth;
}
}
else if (GmmIsYUVPacked(pTexInfo->Format)) /////////////////////////
{
UnitAlignWidth = pPlatform->TexAlign.YUV422.Width;
UnitAlignHeight = pPlatform->TexAlign.YUV422.Height;
// For packed 8/16-bit formats alignment factor of 4 will give us < 16B so expand to 32B
SET_ALIGN_FACTOR(Width, 32);
}
else if(GmmIsCompressed(pGmmLibContext, pTexInfo->Format)) /////////////////////////////
{
uint32_t ElementWidth, ElementHeight, ElementDepth;
pTextureCalc->GetCompressionBlockDimensions(pTexInfo->Format, &ElementWidth, &ElementHeight, &ElementDepth);
UnitAlignWidth = ElementWidth * pPlatform->TexAlign.Compressed.Width;
UnitAlignHeight = ElementHeight * pPlatform->TexAlign.Compressed.Height;
UnitAlignDepth = (pTexInfo->Type == RESOURCE_3D) ? ElementDepth * pPlatform->TexAlign.Compressed.Depth : pPlatform->TexAlign.Compressed.Depth;
}
/// Depth Buffer //////////////////////////////////////////////////
else if(pTexInfo->Flags.Gpu.HiZ)
{
if( (GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN7_CORE) &&
(pTexInfo->BitsPerPixel == 16))
{
UnitAlignWidth = 8; // Gen7 Special Case: HALIGN_8 for 16bpp Depth Buffers
}
else
{
UnitAlignWidth = pPlatform->TexAlign.Depth.Width;
}
UnitAlignHeight = pPlatform->TexAlign.Depth.Height;
}
else if (pTexInfo->Flags.Gpu.Depth)
{
if (pTexInfo->BitsPerPixel == 16)
{
if (pTexInfo->MSAA.NumSamples == 0x2 || pTexInfo->MSAA.NumSamples == 0x8)
{
UnitAlignWidth = pPlatform->TexAlign.Depth_D16_UNORM_2x_8x.Width;
UnitAlignHeight = pPlatform->TexAlign.Depth_D16_UNORM_2x_8x.Height;
}
else
{
UnitAlignWidth = pPlatform->TexAlign.Depth_D16_UNORM_1x_4x_16x.Width;
UnitAlignHeight = pPlatform->TexAlign.Depth_D16_UNORM_1x_4x_16x.Height;
}
SET_ALIGN_FACTOR(Width, 16);
}
else
{
UnitAlignWidth = pPlatform->TexAlign.Depth.Width;
UnitAlignHeight = pPlatform->TexAlign.Depth.Height;
SET_ALIGN_FACTOR(Width, 32);
}
}
/// Separate Stencil //////////////////////////////////////////////
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
UnitAlignWidth = pPlatform->TexAlign.SeparateStencil.Width;
UnitAlignHeight = pPlatform->TexAlign.SeparateStencil.Height;
SET_ALIGN_FACTOR(Width, 16);
}
/// Cross Adapter //////////////////////////////////////////////
else if(pTexInfo->Flags.Info.XAdapter)
{
//Add cross adapter height restriction.
UnitAlignHeight = pPlatform->TexAlign.XAdapter.Height;
UnitAlignWidth = pPlatform->TexAlign.XAdapter.Width;
SET_ALIGN_FACTOR(Width, 128);
__GMM_ASSERT(pTexInfo->MaxLod == 0);
}
else if(((pTexInfo->Flags.Gpu.MCS &&
GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN12_CORE) ||
(pTexInfo->Flags.Gpu.CCS && GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE)) &&
(pTexInfo->MSAA.NumSamples > 1))
{
UnitAlignWidth = 16;
UnitAlignHeight = 4;
SET_ALIGN_FACTOR(Width, 128);
}
else if(pTexInfo->Flags.Wa.__ForceOtherHVALIGN4)
{
UnitAlignWidth = 4;
UnitAlignHeight = 4;
}
else /// All Other ////////////////////////////////////////////////
{
UnitAlignWidth = pPlatform->TexAlign.AllOther.Width;
if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN8_CORE)
{
UnitAlignHeight = pPlatform->TexAlign.AllOther.Height;
// Let VAlign = 16, when bpp == 8 or 16 for both TileX and TileY on BDW
if ((GmmGetWaTable(pGmmLibContext)->WaUseVAlign16OnTileXYBpp816) &&
(pTexInfo->BitsPerPixel == 8 || pTexInfo->BitsPerPixel == 16) &&
(pTexInfo->Flags.Info.TiledX || pTexInfo->Flags.Info.TiledY))
{
UnitAlignHeight = 16;
}
if((GmmGetWaTable(pGmmLibContext)->Wa32bppTileY2DColorNoHAlign4) &&
(pTexInfo->BitsPerPixel == 32 && pTexInfo->Flags.Info.TiledY &&
pTexInfo->MSAA.NumSamples == 1 && pTexInfo->MaxLod > 1) &&
UnitAlignWidth <= 4)
{
UnitAlignWidth = 8;
}
SET_ALIGN_FACTOR(Width, 128);
}
else if(pTexInfo->MSAA.NumSamples <= 1)
{
if ((GmmGetWaTable(pGmmLibContext)->WaValign2For96bppFormats) &&
( pTexInfo->BitsPerPixel == 96 ) )
{
UnitAlignHeight = 2;
}
else if ((GmmGetWaTable(pGmmLibContext)->WaValign2ForR8G8B8UINTFormat) &&
( pTexInfo->Format == GMM_FORMAT_R8G8B8_UINT ) )
{
UnitAlignHeight = 2;
}
else
{
UnitAlignHeight = pPlatform->TexAlign.AllOther.Height;
}
}
else
{
UnitAlignHeight = 4; // Gen6+ Special Case: VALIGN_4 for >= MSAA_4X Render Targets
}
}
//ExistingSysMem override
if(pTexInfo->Flags.Info.ExistingSysMem &&
!pTexInfo->ExistingSysMem.IsGmmAllocated &&
!pTexInfo->ExistingSysMem.IsPageAligned)
{
if(pTexInfo->Flags.Gpu.Texture)
{
UnitAlignWidth = pPlatform->SamplerFetchGranularityWidth;
UnitAlignHeight = pPlatform->SamplerFetchGranularityHeight;
}
else if(pTexInfo->Flags.Gpu.RenderTarget)
{
UnitAlignWidth = (GmmIsYUVPlanar(pTexInfo->Format)) ? 2 : 1;
UnitAlignHeight = 1;
}
}
pTexInfo->Alignment.HAlign = UnitAlignWidth;
pTexInfo->Alignment.VAlign = UnitAlignHeight;
pTexInfo->Alignment.DAlign = UnitAlignDepth;
}
else
{
// Don't reinitialize b/c special-case ResCreates (e.g. MCS) need the
// values from their first pass through here to stick (but they'll come
// through here more than once, with different parameters).
}
GMM_DPF_EXIT;
return GMM_SUCCESS;
} // __GmmTexFillHAlignVAlign
#endif //__cpluscplus
//===========================================================================
// typedef:
// GMM_MIPTAIL_SLOT_OFFSET_REC
//
// Description:
// This structure used to describe the offset between miptail slot and
// miptail starting address
//---------------------------------------------------------------------------
typedef struct GMM_MIPTAIL_SLOT_OFFSET_REC
{
uint32_t X;
uint32_t Y;
uint32_t Z;
}GMM_MIPTAIL_SLOT_OFFSET;
#define GEN9_MIPTAIL_SLOT_OFFSET_1D_SURFACE { \
/* | 128 bpe | 64 bpe | 32 bpe | 16 bpe | 8 bpe | */ \
{ { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 }, { 16384, 0, 0 }, { 32768, 0, 0 } }, \
{ { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 }, { 16384, 0, 0 } }, \
{ { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 } }, \
{ { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 } }, \
{ { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 } }, \
{ { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 } }, \
{ { 48, 0, 0 }, { 96, 0, 0 }, { 192, 0, 0 }, { 384, 0, 0 }, { 768, 0, 0 } }, \
{ { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 } }, \
{ { 28, 0, 0 }, { 56, 0, 0 }, { 112, 0, 0 }, { 224, 0, 0 }, { 448, 0, 0 } }, \
{ { 24, 0, 0 }, { 48, 0, 0 }, { 96, 0, 0 }, { 192, 0, 0 }, { 384, 0, 0 } }, \
{ { 20, 0, 0 }, { 40, 0, 0 }, { 80, 0, 0 }, { 160, 0, 0 }, { 320, 0, 0 } }, \
{ { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 } }, \
{ { 12, 0, 0 }, { 24, 0, 0 }, { 48, 0, 0 }, { 96, 0, 0 }, { 192, 0, 0 } }, \
{ { 8, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 } }, \
{ { 4, 0, 0 }, { 8, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 } }, \
{ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, \
}
#define GEN9_MIPTAIL_SLOT_OFFSET_2D_SURFACE { \
/* | 128 bpe | 64 bpe | 32 bpe | 16 bpe | 8 bpe | */\
{ { 32, 0, 0 }, { 64, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 }, { 128, 0, 0 } }, \
{ { 0, 32, 0 }, { 0, 32, 0 }, { 0, 64, 0 }, { 0, 64, 0 }, { 0, 128, 0 } }, \
{ { 16, 0, 0 }, { 32, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 }, { 64, 0, 0 } }, \
{ { 0, 16, 0 }, { 0, 16, 0 }, { 0, 32, 0 }, { 0, 32, 0 }, { 0, 64, 0 } }, \
{ { 8, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 }, { 32, 0, 0 } }, \
{ { 4, 8, 0 }, { 8, 8, 0 }, { 8, 16, 0 }, { 16, 16, 0 }, { 16, 32, 0 } }, \
{ { 0, 12, 0 }, { 0, 12, 0 }, { 0, 24, 0 }, { 0, 24, 0 }, { 0, 48, 0 } }, \
{ { 0, 8, 0 }, { 0, 8, 0 }, { 0, 16, 0 }, { 0, 16, 0 }, { 0, 32, 0 } }, \
{ { 4, 4, 0 }, { 8, 4, 0 }, { 8, 8, 0 }, { 16, 8, 0 }, { 16, 16, 0 } }, \
{ { 4, 0, 0 }, { 8, 0, 0 }, { 8, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 } }, \
{ { 0, 4, 0 }, { 0, 4, 0 }, { 0, 8, 0 }, { 0, 8, 0 }, { 0, 16, 0 } }, \
{ { 3, 0, 0 }, { 6, 0, 0 }, { 4, 4, 0 }, { 8, 4, 0 }, { 0, 12, 0 } }, \
{ { 2, 0, 0 }, { 4, 0, 0 }, { 4, 0, 0 }, { 8, 0, 0 }, { 0, 8, 0 } }, \
{ { 1, 0, 0 }, { 2, 0, 0 }, { 0, 4, 0 }, { 0, 4, 0 }, { 0, 4, 0 } }, \
{ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, \
}
#define GEN9_MIPTAIL_SLOT_OFFSET_3D_SURFACE { \
/* | 128 bpe | 64 bpe | 32 bpe | 16 bpe | 8 bpe | */ \
{ { 8, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 } }, \
{ { 0, 8, 0 }, { 0, 8, 0 }, { 0, 16, 0 }, { 0, 16, 0 }, { 0, 16, 0 } }, \
{ { 0, 0, 8 }, { 0, 0, 8 }, { 0, 0, 8 }, { 0, 0, 16 }, { 0, 0, 16 } }, \
{ { 4, 0, 0 }, { 8, 0, 0 }, { 8, 0, 0 }, { 8, 0, 0 }, { 16, 0, 0 } }, \
{ { 0, 4, 0 }, { 0, 4, 0 }, { 0, 8, 0 }, { 0, 8, 0 }, { 0, 8, 0 } }, \
{ { 0, 0, 4 }, { 0, 0, 4 }, { 0, 0, 4 }, { 0, 0, 8 }, { 0, 0, 8 } }, \
{ { 3, 0, 0 }, { 6, 0, 0 }, { 4, 4, 0 }, { 0, 4, 4 }, { 0, 4, 4 } }, \
{ { 2, 0, 0 }, { 4, 0, 0 }, { 0, 4, 0 }, { 0, 4, 0 }, { 0, 4, 0 } }, \
{ { 1, 0, 3 }, { 2, 0, 3 }, { 4, 0, 3 }, { 0, 0, 7 }, { 0, 0, 7 } }, \
{ { 1, 0, 2 }, { 2, 0, 2 }, { 4, 0, 2 }, { 0, 0, 6 }, { 0, 0, 6 } }, \
{ { 1, 0, 1 }, { 2, 0, 1 }, { 4, 0, 1 }, { 0, 0, 5 }, { 0, 0, 5 } }, \
{ { 1, 0, 0 }, { 2, 0, 0 }, { 4, 0, 0 }, { 0, 0, 4 }, { 0, 0, 4 } }, \
{ { 0, 0, 3 }, { 0, 0, 3 }, { 0, 0, 3 }, { 0, 0, 3 }, { 0, 0, 3 } }, \
{ { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 2 } }, \
{ { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 } }, \
{ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, \
}
#define GEN10_MIPTAIL_SLOT_OFFSET_1D_SURFACE { \
/* | 128 bpe | 64 bpe | 32 bpe | 16 bpe | 8 bpe | */ \
{ { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 }, { 16384, 0, 0 }, { 32768, 0, 0 } }, \
{ { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 }, { 16384, 0, 0 } }, \
{ { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 } }, \
{ { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 } }, \
{ { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 } }, \
{ { 96, 0, 0 }, { 192, 0, 0 }, { 384, 0, 0 }, { 768, 0, 0 }, { 1536, 0, 0 } }, \
{ { 80, 0, 0 }, { 160, 0, 0 }, { 320, 0, 0 }, { 640, 0, 0 }, { 1280, 0, 0 } }, \
{ { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 } }, \
{ { 48, 0, 0 }, { 96, 0, 0 }, { 192, 0, 0 }, { 384, 0, 0 }, { 768, 0, 0 } }, \
{ { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 } }, \
{ { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 } }, \
{ { 12, 0, 0 }, { 24, 0, 0 }, { 48, 0, 0 }, { 96, 0, 0 }, { 192, 0, 0 } }, \
{ { 8, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 } }, \
{ { 4, 0, 0 }, { 8, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 } }, \
{ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, \
}
#define GEN10_MIPTAIL_SLOT_OFFSET_2D_SURFACE { \
/* | 128 bpe | 64 bpe | 32 bpe | 16 bpe | 8 bpe | */ \
{ { 32, 0, 0 }, { 64, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 }, { 128, 0, 0 } }, \
{ { 0, 32, 0 }, { 0, 32, 0 }, { 0, 64, 0 }, { 0, 64, 0 }, { 0, 128, 0 } }, \
{ { 16, 0, 0 }, { 32, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 }, { 64, 0, 0 } }, \
{ { 0, 16, 0 }, { 0, 16, 0 }, { 0, 32, 0 }, { 0, 32, 0 }, { 0, 64, 0 } }, \
{ { 8, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 }, { 32, 0, 0 } }, \
{ { 4, 8, 0 }, { 8, 8, 0 }, { 8, 16, 0 }, { 16, 16, 0 }, { 16, 32, 0 } }, \
{ { 0, 12, 0 }, { 0, 12, 0 }, { 0, 24, 0 }, { 0, 24, 0 }, { 0, 48, 0 } }, \
{ { 0, 8, 0 }, { 0, 8, 0 }, { 0, 16, 0 }, { 0, 16, 0 }, { 0, 32, 0 } }, \
{ { 4, 4, 0 }, { 8, 4, 0 }, { 8, 8, 0 }, { 16, 8, 0 }, { 16, 16, 0 } }, \
{ { 4, 0, 0 }, { 8, 0, 0 }, { 8, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 } }, \
{ { 0, 4, 0 }, { 0, 4, 0 }, { 0, 8, 0 }, { 0, 8, 0 }, { 0, 16, 0 } }, \
{ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, \
{ { 1, 0, 0 }, { 2, 0, 0 }, { 0, 4, 0 }, { 0, 4, 0 }, { 0, 4, 0 } }, \
{ { 2, 0, 0 }, { 4, 0, 0 }, { 4, 0, 0 }, { 8, 0, 0 }, { 0, 8, 0 } }, \
{ { 3, 0, 0 }, { 6, 0, 0 }, { 4, 4, 0 }, { 8, 4, 0 }, { 0, 12, 0 } }, \
}
#define GEN10_MIPTAIL_SLOT_OFFSET_3D_SURFACE { \
/* | 128 bpe | 64 bpe | 32 bpe | 16 bpe | 8 bpe | */ \
{ { 8, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 } }, \
{ { 0, 8, 0 }, { 0, 8, 0 }, { 0, 16, 0 }, { 0, 16, 0 }, { 0, 16, 0 } }, \
{ { 0, 0, 8 }, { 0, 0, 8 }, { 0, 0, 8 }, { 0, 0, 16 }, { 0, 0, 16 } }, \
{ { 4, 0, 0 }, { 8, 0, 0 }, { 8, 0, 0 }, { 8, 0, 0 }, { 16, 0, 0 } }, \
{ { 0, 4, 0 }, { 0, 4, 0 }, { 0, 8, 0 }, { 0, 8, 0 }, { 0, 8, 0 } }, \
{ { 2, 0, 4 }, { 4, 0, 4 }, { 4, 0, 4 }, { 4, 0, 8 }, { 8, 0, 8 } }, \
{ { 0, 2, 4 }, { 0, 2, 4 }, { 0, 4, 4 }, { 0, 4, 8 }, { 0, 4, 8 } }, \
{ { 0, 0, 4 }, { 0, 0, 4 }, { 0, 0, 4 }, { 0, 0, 8 }, { 0, 0, 8 } }, \
{ { 2, 2, 0 }, { 4, 2, 0 }, { 4, 4, 0 }, { 4, 4, 0 }, { 8, 4, 0 } }, \
{ { 2, 0, 0 }, { 4, 0, 0 }, { 4, 0, 0 }, { 4, 0, 0 }, { 8, 0, 0 } }, \
{ { 0, 2, 0 }, { 0, 2, 0 }, { 0, 4, 0 }, { 0, 4, 0 }, { 0, 4, 0 } }, \
{ { 1, 0, 2 }, { 2, 0, 2 }, { 2, 0, 2 }, { 2, 0, 4 }, { 4, 0, 4 } }, \
{ { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 4 }, { 0, 0, 4 } }, \
{ { 1, 0, 0 }, { 2, 0, 0 }, { 2, 0, 0 }, { 2, 0, 0 }, { 4, 0, 0 } }, \
{ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, \
}
#define GEN11_MIPTAIL_SLOT_OFFSET_1D_SURFACE { \
/* | 128 bpe | 64 bpe | 32 bpe | 16 bpe | 8 bpe | */ \
{ { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 }, { 16384, 0, 0 }, { 32768, 0, 0 } }, \
{ { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 }, { 16384, 0, 0 } }, \
{ { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 }, { 8192, 0, 0 } }, \
{ { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 }, { 4096, 0, 0 } }, \
{ { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 }, { 2048, 0, 0 } }, \
{ { 96, 0, 0 }, { 192, 0, 0 }, { 384, 0, 0 }, { 768, 0, 0 }, { 1536, 0, 0 } }, \
{ { 80, 0, 0 }, { 160, 0, 0 }, { 320, 0, 0 }, { 640, 0, 0 }, { 1280, 0, 0 } }, \
{ { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 }, { 1024, 0, 0 } }, \
{ { 48, 0, 0 }, { 96, 0, 0 }, { 192, 0, 0 }, { 384, 0, 0 }, { 768, 0, 0 } }, \
{ { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 }, { 512, 0, 0 } }, \
{ { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 }, { 256, 0, 0 } }, \
{ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, \
{ { 4, 0, 0 }, { 8, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 } }, \
{ { 8, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 }, { 64, 0, 0 }, { 128, 0, 0 } }, \
{ { 12, 0, 0 }, { 24, 0, 0 }, { 48, 0, 0 }, { 96, 0, 0 }, { 192, 0, 0 } }, \
}
#define GEN11_MIPTAIL_SLOT_OFFSET_2D_SURFACE GEN10_MIPTAIL_SLOT_OFFSET_2D_SURFACE
#define GEN11_MIPTAIL_SLOT_OFFSET_3D_SURFACE { \
/* | 128 bpe | 64 bpe | 32 bpe | 16 bpe | 8 bpe | */ \
{ { 8, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 }, { 16, 0, 0 }, { 32, 0, 0 } }, \
{ { 0, 8, 0 }, { 0, 8, 0 }, { 0, 16, 0 }, { 0, 16, 0 }, { 0, 16, 0 } }, \
{ { 0, 0, 8 }, { 0, 0, 8 }, { 0, 0, 8 }, { 0, 0, 16 }, { 0, 0, 16 } }, \
{ { 4, 0, 0 }, { 8, 0, 0 }, { 8, 0, 0 }, { 8, 0, 0 }, { 16, 0, 0 } }, \
{ { 0, 4, 0 }, { 0, 4, 0 }, { 0, 8, 0 }, { 0, 8, 0 }, { 0, 8, 0 } }, \
{ { 2, 0, 4 }, { 4, 0, 4 }, { 4, 0, 4 }, { 0, 4, 8 }, { 0, 4, 8 } }, \
{ { 1, 0, 4 }, { 2, 0, 4 }, { 0, 4, 4 }, { 0, 0, 12 }, { 0, 0, 12 } }, \
{ { 0, 0, 4 }, { 0, 0, 4 }, { 0, 0, 4 }, { 0, 0, 8 }, { 0, 0, 8 } }, \
{ { 3, 0, 0 }, { 6, 0, 0 }, { 4, 4, 0 }, { 0, 4, 4 }, { 0, 4, 4 } }, \
{ { 2, 0, 0 }, { 4, 0, 0 }, { 4, 0, 0 }, { 0, 4, 0 }, { 0, 4, 0 } }, \
{ { 1, 0, 0 }, { 2, 0, 0 }, { 0, 4, 0 }, { 0, 0, 4 }, { 0, 0, 4 } }, \
{ { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }, \
{ { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 } }, \
{ { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 2 }, { 0, 0, 2 } }, \
{ { 0, 0, 3 }, { 0, 0, 3 }, { 0, 0, 3 }, { 0, 0, 3 }, { 0, 0, 3 } }, \
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,826 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// GMM Interface to return lock or render aligned offset to a mip map
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
/// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO to store offset info
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmTexGetMipMapOffset(GMM_TEXTURE_INFO * pTexInfo,
GMM_REQ_OFFSET_INFO *pReqInfo,
GMM_LIB_CONTEXT * pGmmLibContext)
{
GMM_STATUS Status = GMM_SUCCESS;
bool RestoreRenderReq = false;
GMM_TEXTURE_CALC *pTextureCalc;
GMM_DPF_ENTER;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
__GMM_ASSERT(pReqInfo->CubeFace <= __GMM_NO_CUBE_MAP);
pTextureCalc = GMM_OVERRIDE_TEXTURE_CALC(pTexInfo, pGmmLibContext);
if((pReqInfo->Plane >= GMM_MAX_PLANE) ||
(pReqInfo->Plane < GMM_NO_PLANE) ||
(pReqInfo->MipLevel >= GMM_MAX_MIPMAP))
{
GMM_ASSERTDPF(0, "Invalid parameter!");
return GMM_ERROR;
}
if((pTexInfo->TileMode >= GMM_TILE_MODES) ||
(pTexInfo->TileMode < TILE_NONE))
{
GMM_ASSERTDPF(0, "Invalid parameter!");
return GMM_ERROR;
}
// Retrieve offset info at pReqInfo->MipLevel
if(pReqInfo->ReqLock)
{
if(pReqInfo->ReqRender)
{
pReqInfo->ReqRender = 0;
RestoreRenderReq = true;
}
if(pTextureCalc->GetTexLockOffset(pTexInfo, pReqInfo) != GMM_SUCCESS)
{
GMM_ASSERTDPF(0, "ReqLock failed!");
Status = GMM_ERROR;
}
}
if(RestoreRenderReq == true)
pReqInfo->ReqRender = 1;
if(pReqInfo->ReqRender)
{
if(pTextureCalc->GetTexRenderOffset(pTexInfo, pReqInfo) != GMM_SUCCESS)
{
GMM_ASSERTDPF(0, "ReqRender failed!");
Status = GMM_ERROR;
}
}
if(pReqInfo->ReqStdLayout)
{
if(pTextureCalc->GetTexStdLayoutOffset(pTexInfo, pReqInfo) != GMM_SUCCESS)
{
GMM_ASSERTDPF(0, "ReqStdLayout failed!");
Status = GMM_ERROR;
}
}
GMM_DPF_EXIT;
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates StdLayout offsets and related pitches of
/// subresource..
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
/// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO to store offset info
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmTextureCalc::GetTexStdLayoutOffset(GMM_TEXTURE_INFO * pTexInfo,
GMM_REQ_OFFSET_INFO *pReqInfo)
{
uint32_t ReqArrayIndex;
bool NeedSurfaceSize = false;
__GMM_ASSERT(pTexInfo);
__GMM_ASSERT(pTexInfo->Flags.Info.TiledYs || pTexInfo->Flags.Info.TiledYf);
__GMM_ASSERT(
(pTexInfo->Type == RESOURCE_2D) ||
(pTexInfo->Type == RESOURCE_3D) ||
(pTexInfo->Type == RESOURCE_CUBE));
__GMM_ASSERT(GmmIsPlanar(pTexInfo->Format) == false); // Planar not support
if(pReqInfo->StdLayout.Offset == -1) // Special Req for Surface Size
{
NeedSurfaceSize = true;
ReqArrayIndex = // TODO(Medium): Add planar support.
(pTexInfo->ArraySize * ((pTexInfo->Type == RESOURCE_CUBE) ? 6 : 1));
}
else
{
ReqArrayIndex =
(pReqInfo->ArrayIndex * ((pTexInfo->Type == RESOURCE_CUBE) ? 6 : 1));
}
{
uint32_t TileSize = 0;
if(pTexInfo->Flags.Info.TiledYs)
{
TileSize = GMM_KBYTE(64);
}
else if(pTexInfo->Flags.Info.TiledYf)
{
TileSize = GMM_KBYTE(4);
}
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
uint32_t BytesPerElement = pTexInfo->BitsPerPixel / CHAR_BIT;
GMM_TILE_MODE TileMode = pTexInfo->TileMode;
struct
{
uint32_t Width, Height, Depth;
} Element, Tile;
__GMM_ASSERT(TileMode < GMM_TILE_MODES);
GetCompressionBlockDimensions(
pTexInfo->Format,
&Element.Width,
&Element.Height,
&Element.Depth);
Tile.Width =
(pPlatform->TileInfo[TileMode].LogicalTileWidth / BytesPerElement) *
Element.Width;
Tile.Height =
pPlatform->TileInfo[TileMode].LogicalTileHeight *
Element.Height;
Tile.Depth =
pPlatform->TileInfo[TileMode].LogicalTileDepth *
Element.Depth;
{
GMM_GFX_ADDRESS TargetLodOffset = 0;
GMM_GFX_SIZE_T PrevMipSize = 0;
GMM_GFX_SIZE_T SliceOffset = 0;
GMM_GFX_SIZE_T SlicePitch = 0;
uint32_t Lod;
uint32_t EffectiveMaxLod =
(ReqArrayIndex == 0) ?
pReqInfo->MipLevel :
GFX_MIN(pTexInfo->MaxLod, pTexInfo->Alignment.MipTailStartLod);
pReqInfo->StdLayout.Offset = 0;
for(Lod = 0; Lod <= EffectiveMaxLod; Lod++)
{
GMM_GFX_SIZE_T MipWidth = GmmTexGetMipWidth(pTexInfo, Lod);
uint32_t MipHeight = GmmTexGetMipHeight(pTexInfo, Lod);
uint32_t MipDepth = GmmTexGetMipDepth(pTexInfo, Lod);
uint32_t MipCols = GFX_ULONG_CAST(
GFX_CEIL_DIV(
MipWidth,
Tile.Width));
uint32_t MipRows =
GFX_CEIL_DIV(
MipHeight,
Tile.Height);
uint32_t MipDepthTiles =
GFX_CEIL_DIV(
MipDepth,
Tile.Depth);
uint32_t RowPitch = MipCols * TileSize; // Bytes from one tile row to the next.
uint32_t DepthPitch = RowPitch * MipRows; // Bytes from one depth slice of tiles to the next.
if(Lod <= pTexInfo->Alignment.MipTailStartLod)
{
pReqInfo->StdLayout.Offset += PrevMipSize;
}
if(Lod == pReqInfo->MipLevel)
{
TargetLodOffset = pReqInfo->StdLayout.Offset;
pReqInfo->StdLayout.TileRowPitch = RowPitch;
pReqInfo->StdLayout.TileDepthPitch = DepthPitch;
}
PrevMipSize = DepthPitch * MipDepthTiles;
SlicePitch += DepthPitch;
}
if(pReqInfo->Slice > 0)
{
SliceOffset = SlicePitch * pReqInfo->Slice;
}
if(!NeedSurfaceSize && pReqInfo->MipLevel >= pTexInfo->Alignment.MipTailStartLod)
{
pReqInfo->StdLayout.Offset += (ReqArrayIndex * (pReqInfo->StdLayout.Offset + PrevMipSize)) +
GetMipTailByteOffset(pTexInfo, pReqInfo->MipLevel);
}
else
{
pReqInfo->StdLayout.Offset = ReqArrayIndex * (pReqInfo->StdLayout.Offset + PrevMipSize) +
TargetLodOffset;
}
pReqInfo->StdLayout.Offset += SliceOffset;
}
}
return GMM_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Calculates offset address of a sub resource(i.e. Mip Map, Cube face, volume texture)
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
/// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO to store offset info
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmTextureCalc::GetTexLockOffset(GMM_TEXTURE_INFO * pTexInfo,
GMM_REQ_OFFSET_INFO *pReqInfo)
{
GMM_STATUS Result = GMM_SUCCESS;
GMM_GFX_SIZE_T AddressOffset;
uint32_t Pitch, Slice;
uint32_t MipHeight, MipWidth, MipLevel;
uint32_t NumberOfMipsInSingleRow, SliceRow;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
// set default value
AddressOffset = 0;
Pitch = GFX_ULONG_CAST(pTexInfo->Pitch);
MipLevel = pReqInfo->MipLevel;
Slice = pReqInfo->Slice;
if(GmmIsPlanar(pTexInfo->Format))
{
AddressOffset = GetMipMapByteAddress(pTexInfo, pReqInfo);
pReqInfo->Lock.Offset64 = AddressOffset;
pReqInfo->Lock.Pitch = Pitch;
// Adjust returned pitch for non-uniform-pitch U/V queries...
if((pReqInfo->Plane == GMM_PLANE_U) ||
(pReqInfo->Plane == GMM_PLANE_V))
{
switch(pTexInfo->Format)
{
case GMM_FORMAT_I420:
case GMM_FORMAT_IYUV:
case GMM_FORMAT_YV12:
case GMM_FORMAT_NV11:
pReqInfo->Lock.Pitch /= 2;
break;
case GMM_FORMAT_YVU9:
pReqInfo->Lock.Pitch /= 4;
break;
default:
//Cool--Constant pitch across all planes.
break;
}
}
return Result;
}
switch(pTexInfo->Type)
{
case RESOURCE_3D:
{
if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE)
{
AddressOffset = GFX_ULONG_CAST(GetMipMapByteAddress(pTexInfo, pReqInfo));
// Bytes from one slice to the next...
pReqInfo->Lock.Gen9PlusSlicePitch = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock);
}
else
{
MipHeight = pTexInfo->BaseHeight >> MipLevel;
MipWidth = GFX_ULONG_CAST(pTexInfo->BaseWidth) >> MipLevel;
AlignTexHeightWidth(pTexInfo, &MipHeight, &MipWidth);
// See how many mip can fit in one row
NumberOfMipsInSingleRow = GFX_2_TO_POWER_OF(MipLevel);
SliceRow = Slice / NumberOfMipsInSingleRow;
// get the base address + Slice pitch
AddressOffset = pTexInfo->OffsetInfo.Texture3DOffsetInfo.Offset[MipLevel];
pReqInfo->Lock.Mip0SlicePitch = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Texture3DOffsetInfo.Mip0SlicePitch);
// Actual address is offset based on requested slice
AddressOffset += SliceRow * MipHeight * Pitch;
// Get to particular slice
if(Slice % NumberOfMipsInSingleRow)
{
AddressOffset += (((Slice % NumberOfMipsInSingleRow) *
MipWidth * pTexInfo->BitsPerPixel) >>
3);
}
}
break;
}
case RESOURCE_CUBE:
case RESOURCE_2D:
case RESOURCE_1D:
{
AddressOffset = GetMipMapByteAddress(pTexInfo, pReqInfo);
break;
}
default:
{ // These resources dont' have multiple levels of detail
AddressOffset = 0;
break;
}
}
pReqInfo->Lock.Offset64 = AddressOffset;
pReqInfo->Lock.Pitch = Pitch;
return Result;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Function used to align width and height of texture so that it satisfy our HW
/// restriction
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
/// @param[in] pHeight: ptr to height of mip
/// @param[in] pWidth: ptr to width of mip
///
/////////////////////////////////////////////////////////////////////////////////////
void GmmLib::GmmTextureCalc::AlignTexHeightWidth(GMM_TEXTURE_INFO *pTexInfo,
uint32_t * pHeight,
uint32_t * pWidth)
{
uint32_t MipWidth = 0;
uint32_t MipHeight = 0;
uint32_t UnitAlignHeight = 0;
uint32_t UnitAlignWidth = 0;
uint8_t Compress = 0;
__GMM_ASSERTPTR(pTexInfo, VOIDRETURN);
__GMM_ASSERTPTR(pWidth, VOIDRETURN);
__GMM_ASSERTPTR(pHeight, VOIDRETURN);
__GMM_ASSERTPTR(pGmmLibContext, VOIDRETURN);
MipWidth = *pWidth;
MipHeight = *pHeight;
UnitAlignWidth = pTexInfo->Alignment.HAlign;
UnitAlignHeight = pTexInfo->Alignment.VAlign;
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
MipWidth = GFX_MAX(MipWidth, UnitAlignWidth);
MipHeight = GFX_MAX(MipHeight, UnitAlignHeight);
MipWidth = GFX_ALIGN(MipWidth, UnitAlignWidth);
MipHeight = GFX_ALIGN(MipHeight, UnitAlignHeight);
if(Compress)
{
uint32_t CompressHeight, CompressWidth, CompressDepth;
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
MipWidth /= CompressWidth;
MipHeight /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
{
MipWidth *= 2;
MipHeight /= 2;
}
*pHeight = MipHeight;
*pWidth = MipWidth;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Function used to calculate the render aligned offset of a given surface
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
/// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO
///
/// @return ::GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmTextureCalc::GetTexRenderOffset(GMM_TEXTURE_INFO * pTexInfo,
GMM_REQ_OFFSET_INFO *pReqInfo)
{
const GMM_TILE_INFO * pTileInfo = NULL;
GMM_GFX_SIZE_T AddressOffset = 0;
GMM_GFX_SIZE_T RenderAlignOffset = 0;
uint32_t OffsetX = 0;
uint32_t OffsetY = 0;
uint32_t OffsetZ = 0;
const GMM_PLATFORM_INFO *pPlatform = NULL;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
pTileInfo = &pPlatform->TileInfo[pTexInfo->TileMode];
AddressOffset = GetMipMapByteAddress(pTexInfo, pReqInfo);
if(GMM_IS_TILED(*pTileInfo))
{
uint32_t TileAlignedOffsetX = 0;
uint32_t TileAlignedOffsetY = 0;
GMM_GFX_SIZE_T MipTailByteOffset = 0;
//--- Compute Tile-Aligned Offset, and Corresponding X/Y Offsets -------
// Render/Tiled-Aligned offsets and corresponding X/Y offsets are used
// to program the Surface Base Address and X/Y Offset fields of a
// SURFACE_STATE. For a given subresource, the tiled-aligned offset
// addresses the tile containing the base of the subresource; the X/Y
// offsets then give the additional offsets into the tile of the
// subresource base. (Though in SURFACE_STATE, X Offset is specified in
// pixels, this function will return the X Offset in bytes. Y Offset is
// in pixel rows.)
if((pTexInfo->Flags.Info.TiledYf || GMM_IS_64KB_TILE(pTexInfo->Flags)) &&
(pReqInfo->MipLevel >= pTexInfo->Alignment.MipTailStartLod))
{
MipTailByteOffset = GetMipTailByteOffset(pTexInfo, pReqInfo->MipLevel);
// For MipTail, Offset is really with respect to start of MipTail,
// so taking out individual Mipoffset within miptail region to get correct Tile aligned offset.
AddressOffset -= MipTailByteOffset;
}
if(!pTexInfo->Flags.Info.RedecribedPlanes)
{
GMM_GFX_SIZE_T Pitch = pTexInfo->Pitch;
if(!pTexInfo->Pitch)
{
// If no pitch exists, but the surface is still marked as tiled, then it is a 1D TileYf/Ys surface.
// Technically no pitch exists for 1D surfaces, but we will fake it to make calculations work below.
// Since 1D surfaces only have an X-dimension, this Pitch calculation is only used for OffsetX calculation.
Pitch = pTexInfo->Size;
}
if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
{
OffsetX = GFX_ULONG_CAST(AddressOffset % Pitch);
TileAlignedOffsetX = GFX_ALIGN_FLOOR(OffsetX, pTileInfo->LogicalTileWidth / 2);
OffsetX -= TileAlignedOffsetX;
}
else
{
OffsetX = GFX_ULONG_CAST(AddressOffset % Pitch);
TileAlignedOffsetX = GFX_ALIGN_FLOOR(OffsetX, pTileInfo->LogicalTileWidth);
OffsetX -= TileAlignedOffsetX;
}
if(pTexInfo->Pitch)
{
if(pTexInfo->Flags.Gpu.SeparateStencil && pTexInfo->Flags.Info.TiledW)
{
//Expt: YOffset ignore row-interleave -- verify both 2d/3d mips
OffsetY = GFX_ULONG_CAST(AddressOffset / pTexInfo->Pitch);
OffsetY *= 2;
TileAlignedOffsetY = GFX_ALIGN_FLOOR(OffsetY, pTileInfo->LogicalTileHeight * 2 * pTileInfo->LogicalTileDepth);
OffsetY -= TileAlignedOffsetY;
TileAlignedOffsetY /= 2;
}
else
{
OffsetY = GFX_ULONG_CAST(AddressOffset / pTexInfo->Pitch);
TileAlignedOffsetY = GFX_ALIGN_FLOOR(OffsetY, pTileInfo->LogicalTileHeight * pTileInfo->LogicalTileDepth);
OffsetY -= TileAlignedOffsetY;
}
}
RenderAlignOffset =
TileAlignedOffsetY * pTexInfo->Pitch +
(TileAlignedOffsetX / pTileInfo->LogicalTileWidth) * pTileInfo->LogicalSize;
// For Gen9+, Miptail Lods should be reported in a way that
// - Base Address equals tile-aligned "Miptail start address"
// - OffsetX equals to offset (in bytes) from "Miptail start Lod" to "current Lod" in geometric X direction
// - OffsetY and OffsetZ are their pixel distance from "Miptail start Lod" to "current Lod" in geometric Y, Z directions
// Note: only Tile Yf and TileYs have Miptails and their Mips are always "tile aligned"
if((pTexInfo->Flags.Info.TiledYf || GMM_IS_64KB_TILE(pTexInfo->Flags)) &&
(pReqInfo->MipLevel >= pTexInfo->Alignment.MipTailStartLod) &&
// Planar surfaces do not support MIPs
!GmmIsPlanar(pTexInfo->Format))
{
GetMipTailGeometryOffset(pTexInfo, pReqInfo->MipLevel, &OffsetX, &OffsetY, &OffsetZ);
}
}
else
{
// Std swizzled and UV packed planes begin at tile-aligned
// offsets and do not support MIPs, so no adjustment is needed
RenderAlignOffset = AddressOffset;
OffsetX = OffsetY = OffsetZ = 0;
}
}
else
{
// Linear case make sure Render address is DWORD aligned.
RenderAlignOffset = GFX_ALIGN_FLOOR(AddressOffset, GMM_BYTES(4));
if(pTexInfo->Pitch)
{
OffsetX = GFX_ULONG_CAST((AddressOffset - RenderAlignOffset) % pTexInfo->Pitch);
OffsetY = GFX_ULONG_CAST((AddressOffset - RenderAlignOffset) / pTexInfo->Pitch);
}
else
{
// One-dimensional textures (no height)
OffsetX = GFX_ULONG_CAST(AddressOffset - RenderAlignOffset);
OffsetY = 0;
}
}
pReqInfo->Render.Offset64 = RenderAlignOffset;
pReqInfo->Render.XOffset = GFX_ULONG_CAST(OffsetX);
pReqInfo->Render.YOffset = GFX_ULONG_CAST(OffsetY);
pReqInfo->Render.ZOffset = GFX_ULONG_CAST(OffsetZ);
return GMM_SUCCESS;
} // __GmmGetRenderAlignAddress
/////////////////////////////////////////////////////////////////////////////////////
/// Function used to calculate byte address of a specified mip map
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
/// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO
///
/// @return ::GMM_GFX_SIZE_T byte offset
/////////////////////////////////////////////////////////////////////////////////////
GMM_GFX_SIZE_T GmmLib::GmmTextureCalc::GetMipMapByteAddress(GMM_TEXTURE_INFO * pTexInfo,
GMM_REQ_OFFSET_INFO *pReqInfo)
{
GMM_GFX_SIZE_T ArrayQPitch, MipMapByteAddress, Pitch;
uint32_t MipLevel;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
__GMM_ASSERT(!(pTexInfo->Flags.Gpu.CCS && !pTexInfo->Flags.Gpu.UnifiedAuxSurface));
__GMM_ASSERT(pReqInfo->Plane < GMM_MAX_PLANE);
MipLevel = pReqInfo->MipLevel;
Pitch = pTexInfo->Pitch;
ArrayQPitch = pReqInfo->ReqRender ?
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchRender :
pTexInfo->OffsetInfo.Texture2DOffsetInfo.ArrayQPitchLock;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
if(pTexInfo->Type == RESOURCE_3D && !pTexInfo->Flags.Info.Linear)
{
ArrayQPitch *= pPlatform->TileInfo[pTexInfo->TileMode].LogicalTileDepth;
}
if((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN8_CORE) &&
((pTexInfo->MSAA.NumSamples > 1) &&
!(pTexInfo->Flags.Gpu.Depth ||
pTexInfo->Flags.Gpu.SeparateStencil ||
GMM_IS_64KB_TILE(pTexInfo->Flags) ||
pTexInfo->Flags.Info.TiledYf)))
{
ArrayQPitch *= pTexInfo->MSAA.NumSamples;
}
if(GmmIsPlanar(pTexInfo->Format))
{
uint32_t Plane = pReqInfo->Plane;
uint32_t OffsetX = 0;
uint32_t OffsetY = 0;
if(Plane < GMM_MAX_PLANE)
{
OffsetX = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.X[Plane]);
OffsetY = GFX_ULONG_CAST(pTexInfo->OffsetInfo.Plane.Y[Plane]);
}
MipMapByteAddress = (OffsetY * Pitch) + OffsetX;
__GMM_ASSERT(!pReqInfo->ArrayIndex || (pReqInfo->ArrayIndex < pTexInfo->ArraySize));
MipMapByteAddress += (pTexInfo->OffsetInfo.Plane.ArrayQPitch * pReqInfo->ArrayIndex);
}
else
{
switch(pTexInfo->Type)
{
case RESOURCE_CUBE:
{
uint32_t CubeFace = pReqInfo->CubeFace;
GMM_ASSERTDPF( // Validate Cube Map Params...
(!pReqInfo->ArrayIndex || (pReqInfo->ArrayIndex < pTexInfo->ArraySize)) &&
(pReqInfo->CubeFace < __GMM_MAX_CUBE_FACE) &&
(pReqInfo->CubeFace != __GMM_NO_CUBE_MAP) &&
(pReqInfo->Plane == GMM_NO_PLANE) &&
(pReqInfo->Slice == 0),
"Invalid parameter!");
// Support for CubeMap Arrays using 2D Arrays
MipMapByteAddress = pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[MipLevel];
MipMapByteAddress += (ArrayQPitch * ((6 * pReqInfo->ArrayIndex) + CubeFace));
break;
}
case RESOURCE_2D:
case RESOURCE_1D:
{
MipMapByteAddress = pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[MipLevel];
if(pReqInfo->ArrayIndex)
{
MipMapByteAddress += (ArrayQPitch * pReqInfo->ArrayIndex);
}
break;
}
case RESOURCE_3D:
{
if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE)
{
MipMapByteAddress = pTexInfo->OffsetInfo.Texture2DOffsetInfo.Offset[MipLevel];
if(pReqInfo->Slice)
{
MipMapByteAddress += (ArrayQPitch * pReqInfo->Slice);
}
}
else
{
MipMapByteAddress = Get3DMipByteAddress(pTexInfo, pReqInfo);
}
break;
}
default:
{ // These resources don't have multiple levels of detail
MipMapByteAddress = 0;
break;
}
}
}
MipMapByteAddress += pTexInfo->Flags.Gpu.S3d ?
GetDisplayFrameOffset(pTexInfo, pReqInfo) :
0;
return MipMapByteAddress;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Utility function used to calculate byte address to a mip slice
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
/// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO
///
/// @return byte offset
/////////////////////////////////////////////////////////////////////////////////////
GMM_GFX_SIZE_T GmmLib::GmmTextureCalc::Get3DMipByteAddress(GMM_TEXTURE_INFO * pTexInfo,
GMM_REQ_OFFSET_INFO *pReqInfo)
{
uint32_t MipsInThisRow, PlaneRows;
uint32_t MipHeight, MipWidth;
uint32_t UnitAlignHeight, UnitAlignWidth;
GMM_GFX_SIZE_T MipMapByteAddress, ExtraBytes;
uint32_t Slice, MipLevel, Pitch;
uint8_t Compress;
GMM_RESOURCE_FORMAT GenericFormat;
uint32_t CompressHeight, CompressWidth, CompressDepth;
__GMM_ASSERTPTR(pGmmLibContext, 0);
GenericFormat = pTexInfo->Format;
Slice = pReqInfo->Slice;
MipLevel = pReqInfo->MipLevel;
Pitch = GFX_ULONG_CAST(pTexInfo->Pitch);
// For slice 0 for any mip address is simple and stored in table
if(Slice == 0)
{
MipMapByteAddress = pTexInfo->OffsetInfo.Texture3DOffsetInfo.Offset[MipLevel];
}
// For any slice
else
{
MipMapByteAddress = pTexInfo->OffsetInfo.Texture3DOffsetInfo.Offset[MipLevel];
// See how many mip can fit in one row
MipsInThisRow = GFX_2_TO_POWER_OF(MipLevel);
PlaneRows = Slice / MipsInThisRow;
// make sure we get the height and mip of base level
MipWidth = GFX_ULONG_CAST(pTexInfo->BaseWidth);
MipHeight = pTexInfo->BaseHeight;
MipWidth >>= MipLevel;
MipHeight >>= MipLevel;
UnitAlignWidth = pTexInfo->Alignment.HAlign;
UnitAlignHeight = pTexInfo->Alignment.VAlign;
Compress = GmmIsCompressed(pGmmLibContext, pTexInfo->Format);
GetCompressionBlockDimensions(pTexInfo->Format, &CompressWidth, &CompressHeight, &CompressDepth);
// clamp such that mip height is at least min height
MipHeight = GFX_MAX(MipHeight, UnitAlignHeight);
MipHeight = GFX_ALIGN(MipHeight, UnitAlignHeight);
// clamp such that mip width is at least min width
MipWidth = GFX_MAX(MipWidth, UnitAlignWidth);
MipWidth = GFX_ALIGN(MipWidth, UnitAlignWidth);
if(Compress)
{
MipWidth /= CompressWidth;
MipHeight /= CompressHeight;
}
else if(pTexInfo->Flags.Gpu.SeparateStencil)
{
MipWidth *= 2;
MipHeight /= 2;
}
ExtraBytes = PlaneRows * MipHeight * Pitch;
ExtraBytes += ((Slice % MipsInThisRow) *
MipWidth * pTexInfo->BitsPerPixel) >>
3;
// get address offset
MipMapByteAddress += ExtraBytes;
}
return MipMapByteAddress;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Utility function calculates a byte offset from the base of the allocation
// to L frame, R frame, or blank region.
///
/// @param[in] pTexInfo: ptr to ::GMM_TEXTURE_INFO
/// @param[in] pReqInfo: ptr to GMM_REQ_OFFSET_INFO
///
/// @return byte offset
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GmmLib::GmmTextureCalc::GetDisplayFrameOffset(GMM_TEXTURE_INFO * pTexInfo,
GMM_REQ_OFFSET_INFO *pReqInfo)
{
uint32_t Offset;
__GMM_ASSERTPTR(pTexInfo, GMM_ERROR);
__GMM_ASSERTPTR(pReqInfo, GMM_ERROR);
switch(pReqInfo->Frame)
{
case GMM_DISPLAY_L:
Offset = 0;
break;
case GMM_DISPLAY_R:
Offset = pTexInfo->S3d.RFrameOffset;
break;
case GMM_DISPLAY_BLANK_AREA:
Offset = pTexInfo->S3d.BlankAreaOffset;
break;
default:
Offset = 0;
GMM_ASSERTDPF(0, "Unknown Frame Type!");
break;
}
return Offset;
}

View File

@ -0,0 +1,462 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
/////////////////////////////////////////////////////////////////////////////////////
/// This function does any special-case conversion from client-provided pseudo creation
/// parameters to actual parameters for Hiz, CCS, SeparateStencil and Depth buffers.
///
/// @param[in] pTexInfo: Reference to ::GMM_TEXTURE_INFO
///
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmTextureCalc::PreProcessTexSpecialCases(GMM_TEXTURE_INFO *pTexInfo)
{
GMM_STATUS Status = GMM_SUCCESS;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
if(!pTexInfo->Flags.Gpu.CCS &&
!pTexInfo->Flags.Gpu.MCS &&
!pTexInfo->Flags.Gpu.HiZ &&
!pTexInfo->Flags.Gpu.SeparateStencil &&
!pTexInfo->Flags.Gpu.MMC)
{
// Fast-out for non-special-cases.
}
else if(pTexInfo->Flags.Gpu.HiZ) // ######################################
{
// With HiZ surface creation, clients send the size/etc. parameters of
// the associated Depth Buffer--and here we convert to the appropriate
// HiZ creation parameters...
if((pTexInfo->BaseWidth > 0) &&
(pTexInfo->BaseWidth <= pPlatform->HiZ.MaxWidth) &&
(pTexInfo->BaseHeight > 0) &&
(pTexInfo->BaseHeight <= pPlatform->HiZ.MaxHeight) &&
(pTexInfo->Depth <= ((pTexInfo->Type == RESOURCE_3D) ?
pPlatform->HiZ.MaxDepth :
1)) &&
(pTexInfo->ArraySize <= ((pTexInfo->Type == RESOURCE_3D) ?
1 :
(pTexInfo->Type == RESOURCE_CUBE) ?
pPlatform->HiZ.MaxArraySize / 6 :
pPlatform->HiZ.MaxArraySize)) &&
// SKL+ does not support HiZ surfaces for 1D and 3D surfaces
((GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) < IGFX_GEN9_CORE) ||
(pTexInfo->Type != RESOURCE_1D && pTexInfo->Type != RESOURCE_3D)))
{
uint32_t Z_Width, Z_Height, Z_Depth;
// Latch Z_[Width/Height/Depth]...
Z_Width = GFX_ULONG_CAST(pTexInfo->BaseWidth);
Z_Height = pTexInfo->BaseHeight;
if((pTexInfo->Type == RESOURCE_1D) ||
(pTexInfo->Type == RESOURCE_2D))
{
Z_Depth = GFX_MAX(pTexInfo->ArraySize, 1);
}
else if(pTexInfo->Type == RESOURCE_3D)
{
Z_Depth = pTexInfo->Depth;
}
else if(pTexInfo->Type == RESOURCE_CUBE)
{
// HW doesn't allow HiZ cube arrays, but GMM is allowing because
// clients will redescribe depth/HiZ cube arrays as 2D arrays.
Z_Depth = 6 * GFX_MAX(pTexInfo->ArraySize, 1);
}
else
{
__GMM_ASSERT(0); // Illegal--Should have caught at upper IF check.
Z_Depth = 0;
}
// HZ_[Width/Height/QPitch] Calculation...
{
uint32_t h0, h1, hL, i, NumSamples, QPitch, Z_HeightL;
uint32_t HZ_HAlign = 16, HZ_VAlign = 8;
uint8_t HZ_DepthRows = pPlatform->HiZPixelsPerByte;
// HZ operates in pixel space starting from SKL. So, it does not care
// whether the depth buffer is in MSAA mode or not.
NumSamples =
(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN9_CORE) ?
1 :
pTexInfo->MSAA.NumSamples;
pTexInfo->BaseWidth = ExpandWidth(Z_Width, HZ_HAlign, NumSamples);
h0 = ExpandHeight(Z_Height, HZ_VAlign, NumSamples);
Z_Height = GmmTexGetMipHeight(pTexInfo, 1);
h1 = ExpandHeight(Z_Height, HZ_VAlign, NumSamples);
if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN8_CORE)
{
if(pTexInfo->Type == RESOURCE_3D)
{
for(i = 0, Z_HeightL = 0; i <= pTexInfo->MaxLod; i++)
{
Z_Height = GmmTexGetMipHeight(pTexInfo, i);
hL = ExpandHeight(Z_Height, HZ_VAlign, NumSamples);
Z_HeightL += (hL * GFX_MAX(1, (Z_Depth / GFX_2_TO_POWER_OF(i))));
}
pTexInfo->ArraySize = 0;
pTexInfo->BaseHeight = Z_HeightL / 2;
}
else
{
for(i = 2, Z_HeightL = 0; i <= pTexInfo->MaxLod; i++)
{
Z_Height = GmmTexGetMipHeight(pTexInfo, i);
Z_HeightL += ExpandHeight(Z_Height, HZ_VAlign, NumSamples);
}
QPitch =
(pTexInfo->MaxLod > 0) ?
(h0 + GFX_MAX(h1, Z_HeightL)) :
h0;
QPitch /= HZ_DepthRows;
pTexInfo->ArraySize = Z_Depth;
pTexInfo->BaseHeight = QPitch;
}
pTexInfo->Alignment.HAlign = HZ_HAlign;
pTexInfo->Alignment.VAlign = HZ_VAlign / HZ_DepthRows;
}
else //if (GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN7_CORE)
{
if(pTexInfo->Type == RESOURCE_3D)
{
for(i = 0, Z_HeightL = 0; i <= pTexInfo->MaxLod; i++)
{
hL = ExpandHeight(Z_Height >> i, HZ_VAlign, NumSamples);
Z_HeightL += (hL * GFX_MAX(1, (Z_Depth / GFX_2_TO_POWER_OF(i))));
}
pTexInfo->BaseHeight = Z_HeightL / 2;
}
else
{
QPitch = h0 + h1 + 12 * HZ_VAlign;
pTexInfo->BaseHeight = GFX_CEIL_DIV((QPitch * Z_Depth / 2), 8) * 8;
}
pTexInfo->ArraySize = 1;
}
}
/// Native HZ Params //////////////////////////////////////////////////
pTexInfo->BitsPerPixel = 8;
pTexInfo->Depth = 1;
pTexInfo->Format = GMM_FORMAT_GENERIC_8BIT;
pTexInfo->MaxLod = 0;
pTexInfo->MSAA.NumSamples = 1;
pTexInfo->MSAA.SamplePattern = GMM_MSAA_DISABLED;
pTexInfo->Type = RESOURCE_2D;
// HiZ Always Tile-Y
pTexInfo->Flags.Info.Linear = 0;
pTexInfo->Flags.Info.TiledW = 0;
pTexInfo->Flags.Info.TiledX = 0;
pTexInfo->Flags.Info.TiledYf = 0;
GMM_SET_64KB_TILE(pTexInfo->Flags, 0, pGmmLibContext);
GMM_SET_4KB_TILE(pTexInfo->Flags, 1, pGmmLibContext);
}
else
{
GMM_ASSERTDPF(0, "Illegal HiZ creation parameters!");
Status = GMM_ERROR;
}
} // HiZ
else if(pTexInfo->Flags.Gpu.CCS ||
pTexInfo->Flags.Gpu.MCS) // ######################################
{
// With CCS surface creation, clients send height, width, depth, etc. of
// the associated RenderTarget--and here we convert to the appropriate CCS
// creation parameters...
__GMM_ASSERT((!pGmmLibContext->GetSkuTable().FtrTileY ||
(pTexInfo->Flags.Info.Linear + pTexInfo->Flags.Info.TiledW + pTexInfo->Flags.Info.TiledX + pTexInfo->Flags.Info.TiledY)) == 1);
__GMM_ASSERT((pGmmLibContext->GetSkuTable().FtrTileY || (pTexInfo->Flags.Info.Linear + pTexInfo->Flags.Info.Tile4 + pTexInfo->Flags.Info.Tile64)) == 1);
__GMM_ASSERT((pTexInfo->MSAA.NumSamples == 1) || (pTexInfo->MSAA.NumSamples == 2) || (pTexInfo->MSAA.NumSamples == 4) ||
(pTexInfo->MSAA.NumSamples == 8) || (pTexInfo->MSAA.NumSamples == 16));
Status = pGmmLibContext->GetTextureCalc()->MSAACCSUsage(pTexInfo);
if(!pTexInfo->Flags.Gpu.__NonMsaaLinearCCS)
{
// CCS Always Tile-Y (Even for Non-MSAA FastClear.)
pTexInfo->Flags.Info.Linear = 0;
pTexInfo->Flags.Info.TiledW = 0;
pTexInfo->Flags.Info.TiledX = 0;
pTexInfo->Flags.Info.TiledYf = 0;
GMM_SET_64KB_TILE(pTexInfo->Flags, 0, pGmmLibContext);
GMM_SET_4KB_TILE(pTexInfo->Flags, 1, pGmmLibContext);
//Clear compression request in CCS
pTexInfo->Flags.Info.RenderCompressed = 0;
pTexInfo->Flags.Info.MediaCompressed = 0;
}
} // CCS
else if(pTexInfo->Flags.Gpu.SeparateStencil) // ##########################
{
// Seperate stencil sizing is based on the associated depth buffer
// size, however UMD manages this sizing, and GMM will allocate any
// arbitrarily sized stencil. Stencils do have specific tiling
// requirements however, which is handled below.
if((pTexInfo->BaseWidth > 0) &&
(pTexInfo->BaseHeight > 0))
{
__GMM_ASSERT(pTexInfo->BitsPerPixel == 8);
if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) < IGFX_GEN7_CORE)
{
GMM_ASSERTDPF((pTexInfo->MaxLod == 0), "Stencil Buffer LOD's not supported!");
}
if(pGmmLibContext->GetSkuTable().FtrTileY)
{
// Separate Stencil Tile-W Gen8-Gen11, otherwise Tile-Y
pTexInfo->Flags.Info.Linear = 0;
pTexInfo->Flags.Info.TiledX = 0;
pTexInfo->Flags.Info.TiledYf = 0;
pTexInfo->Flags.Info.TiledW = 0;
GMM_SET_4KB_TILE(pTexInfo->Flags, 0, pGmmLibContext);
GMM_SET_64KB_TILE(pTexInfo->Flags, 0, pGmmLibContext);
if(GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) >= IGFX_GEN8_CORE &&
GFX_GET_CURRENT_RENDERCORE(pPlatform->Platform) <= IGFX_GEN11_CORE)
{
pTexInfo->Flags.Info.TiledW = 1;
}
else
{
GMM_SET_4KB_TILE(pTexInfo->Flags, 1, pGmmLibContext);
}
}
else
{
__GMM_ASSERT(pTexInfo->Flags.Info.Tile4 + pTexInfo->Flags.Info.Tile64 == 1);
}
}
else
{
GMM_ASSERTDPF(0, "Illegal Separate Stencil creation parameters!");
Status = GMM_ERROR;
}
} // Separate Stencil
else if(pTexInfo->Flags.Gpu.MMC && pTexInfo->Flags.Gpu.UnifiedAuxSurface)
{
pTexInfo->Flags.Gpu.__NonMsaaLinearCCS = 1;
pTexInfo->Flags.Info.Linear = 1;
}
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// This function performs rough estimate of memory requirement between 4KB Tile vs
/// 64KB Tile surfaces and if the memory wastage due to padding/alignment exceeds
/// configured threshold, then optimize to demote the surface to 4KB Tile.
///
/// @param[in] pTexInfo: Reference to ::GMM_TEXTURE_INFO
/// returns 1 if optimization to demote to 4KB tile is required otherwise 0
///
/////////////////////////////////////////////////////////////////////////////////////
uint8_t GmmLib::GmmTextureCalc::SurfaceRequires64KBTileOptimization(GMM_TEXTURE_INFO *pTexInfo)
{
GMM_STATUS Status = GMM_SUCCESS;
const GMM_PLATFORM_INFO *pPlatform = GMM_OVERRIDE_PLATFORM_INFO(pTexInfo, pGmmLibContext);
uint32_t Size4KbTile, Size64KbTile;
// Discard the surface if not eligible for 4KB Tile.
// All YUV formats restricted with default Tile64 across clients
if((pTexInfo->MSAA.NumSamples > 1) ||
pTexInfo->Flags.Gpu.TiledResource ||
pTexInfo->Flags.Gpu.HiZ ||
(!pTexInfo->Flags.Info.Tile64))
{
return 0;
}
// Calc Surf size for 64KB Tile.
// Ignoring the CCS/AuxSurf dimensions since its proportional to main surface size
{
GMM_TEXTURE_INFO Surf = {};
uint32_t ExpandedArraySize, BitsPerPixel;
uint32_t SliceHeight, SliceWidth, Pitch;
uint32_t BlockHeight = 0;
uint32_t HAlign, VAlign, DAlign, CompressHeight, CompressWidth, CompressDepth;
Surf = *pTexInfo;
//Get HAlign/VAlign
if((Status = __GmmTexFillHAlignVAlign(&Surf, pGmmLibContext)) != GMM_SUCCESS)
{
__GMM_ASSERT(0);
return 0;
}
HAlign = Surf.Alignment.HAlign;
VAlign = Surf.Alignment.VAlign;
DAlign = Surf.Alignment.DAlign;
// Set Tile Mode
SetTileMode(&Surf);
BitsPerPixel = Surf.BitsPerPixel;
ExpandedArraySize =
GFX_MAX(Surf.ArraySize, 1) *
((Surf.Type == RESOURCE_CUBE) ? 6 : 1) * // Cubemaps simply 6-element, 2D arrays.
((Surf.Type == RESOURCE_3D) ? GFX_MAX(Surf.Depth, 1) : 1); // 3D's simply 2D arrays for sizing.
if(GMM_IS_64KB_TILE(Surf.Flags))
{
ExpandedArraySize = GFX_CEIL_DIV(ExpandedArraySize, pPlatform->TileInfo[Surf.TileMode].LogicalTileDepth);
}
// For Mipped Surface, Approx SliceHeight = VAlign(Lod0Height) * Mipped ? 1.5 : 1;
SliceHeight = GFX_ALIGN(Surf.BaseHeight, VAlign);
if(Surf.MaxLod > 1)
{
SliceHeight = (GFX_ALIGN(Surf.BaseHeight, VAlign) * 3) / 2;
}
uint8_t Compress = GmmIsCompressed(pGmmLibContext, Surf.Format);
GetCompressionBlockDimensions(Surf.Format, &CompressWidth, &CompressHeight, &CompressDepth);
SliceWidth = __GMM_EXPAND_WIDTH(this, GFX_ULONG_CAST(Surf.BaseWidth), HAlign, &Surf);
BlockHeight = SliceHeight * ExpandedArraySize;
if(Compress)
{
SliceWidth = GFX_CEIL_DIV(SliceWidth, CompressWidth);
BlockHeight = GFX_CEIL_DIV(BlockHeight, CompressHeight);
}
// Default pitch
Pitch = SliceWidth * BitsPerPixel >> 3;
if(GMM_IS_TILED(pPlatform->TileInfo[Surf.TileMode]))
{
Pitch = GFX_ALIGN(Pitch, pPlatform->TileInfo[Surf.TileMode].LogicalTileWidth);
BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[Surf.TileMode].LogicalTileHeight);
}
// Calculate Tile aligned size.
Size64KbTile = BlockHeight * Pitch;
if(pTexInfo->Type == RESOURCE_3D && !pTexInfo->Flags.Info.Linear)
{
Size64KbTile *= pPlatform->TileInfo[Surf.TileMode].LogicalTileDepth;
}
}
// Calc Surf size for 4KB Tile
// Ignoring the CCS/AuxSurf dimensions since its proportional to main surface size
{
GMM_TEXTURE_INFO Surf = {};
uint32_t ExpandedArraySize, BitsPerPixel;
uint32_t SliceHeight, SliceWidth, Pitch;
uint32_t BlockHeight = 0;
uint32_t HAlign, VAlign, DAlign, CompressHeight, CompressWidth, CompressDepth;
Surf = *pTexInfo;
Surf.Flags.Info.Tile4 = 1;
Surf.Flags.Info.Tile64 = 0;
//Get HAlign/VAlign
if((Status = __GmmTexFillHAlignVAlign(&Surf, pGmmLibContext)) != GMM_SUCCESS)
{
Status = GMM_ERROR;
return Status;
}
HAlign = Surf.Alignment.HAlign;
VAlign = Surf.Alignment.VAlign;
DAlign = Surf.Alignment.DAlign;
// Set Tile Mode
SetTileMode(&Surf);
BitsPerPixel = Surf.BitsPerPixel;
ExpandedArraySize =
GFX_MAX(Surf.ArraySize, 1) *
((Surf.Type == RESOURCE_CUBE) ? 6 : 1) * // Cubemaps simply 6-element, 2D arrays.
((Surf.Type == RESOURCE_3D) ? GFX_MAX(Surf.Depth, 1) : 1); // 3D's simply 2D arrays for sizing.
if(GMM_IS_64KB_TILE(Surf.Flags))
{
ExpandedArraySize = GFX_CEIL_DIV(ExpandedArraySize, pPlatform->TileInfo[Surf.TileMode].LogicalTileDepth);
}
// For Mipped Surface, Approx SliceHeight = VAlign(Lod0Height) * Mipped ? 1.5 : 1;
SliceHeight = GFX_ALIGN(Surf.BaseHeight, VAlign);
if(Surf.MaxLod > 1)
{
SliceHeight = (GFX_ALIGN(Surf.BaseHeight, VAlign) * 3) / 2;
}
uint8_t Compress = GmmIsCompressed(pGmmLibContext, Surf.Format);
GetCompressionBlockDimensions(Surf.Format, &CompressWidth, &CompressHeight, &CompressDepth);
SliceWidth = __GMM_EXPAND_WIDTH(this, GFX_ULONG_CAST(Surf.BaseWidth), HAlign, &Surf);
BlockHeight = SliceHeight * ExpandedArraySize;
if(Compress)
{
SliceWidth = GFX_CEIL_DIV(SliceWidth, CompressWidth);
BlockHeight = GFX_CEIL_DIV(BlockHeight, CompressHeight);
}
// Default pitch
Pitch = SliceWidth * BitsPerPixel >> 3;
if(GMM_IS_TILED(pPlatform->TileInfo[Surf.TileMode]))
{
Pitch = GFX_ALIGN(Pitch, pPlatform->TileInfo[Surf.TileMode].LogicalTileWidth);
BlockHeight = GFX_ALIGN(BlockHeight, pPlatform->TileInfo[Surf.TileMode].LogicalTileHeight);
}
// Calculate Tile aligned size.
Size4KbTile = BlockHeight * Pitch;
}
// check if 64KB tiled resource size exceeds memory wastage threshold.
if(((Size4KbTile * (100 + (GMM_GFX_SIZE_T)pGmmLibContext->GetAllowedPaddingFor64KBTileSurf())) / 100) < Size64KbTile)
{
return 1;
}
return 0;
}

View File

@ -0,0 +1,949 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Description: AUX-Table management functions
(contains functions to assign memory to
AUX-Tables with valid entries,
and update their entries on request)
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "../TranslationTable/GmmUmdTranslationTable.h"
#if !defined(__GMM_KMD__)
//=============================================================================
//
// Function: MapNullCCS
//
// Desc: Maps given resource, with dummy null-ccs chain, on Aux Table
//
// Caller: UpdateAuxTable (map op for null-tiles)
//
// Parameters:
// UmdContext: Caller-thread specific info (regarding BB for TR-Aux udpate, cmdQ to use etc)
// BaseAdr: Start adr of main surface
// Size: Main-surface size in bytes
// PartialL1e: Aux-metadata other than AuxVA
// DoNotWait: 1 for CPU update, 0 for async(Gpu) update
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::AuxTable::MapNullCCS(GMM_UMD_SYNCCONTEXT *UmdContext, GMM_GFX_ADDRESS BaseAdr, GMM_GFX_SIZE_T Size, uint64_t PartialL1e, uint8_t DoNotWait)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_GFX_SIZE_T L1TableSize = (GMM_L1_SIZE(AUXTT, GetGmmLibContext())) * (!WA16K(GetGmmLibContext()) ? GMM_KBYTE(64) : GMM_KBYTE(16)); //Each AuxTable entry maps 16K main-surface
GMM_GFX_ADDRESS Addr = 0;
GMM_GFX_ADDRESS L3GfxAddress = 0;
GMM_CLIENT ClientType;
GET_GMM_CLIENT_TYPE(pClientContext, ClientType);
EnterCriticalSection(&TTLock);
DoNotWait |= (!UmdContext || !UmdContext->pCommandQueueHandle);
if(TTL3.L3Handle)
{
L3GfxAddress = TTL3.GfxAddress;
}
else
{
LeaveCriticalSection(&TTLock);
return GMM_ERROR;
}
if(!DoNotWait)
{
PageTableMgr->TTCb.pfPrologTranslationTable(
UmdContext->pCommandQueueHandle);
}
// For each L1 table
for(Addr = GFX_ALIGN_FLOOR(BaseAdr, L1TableSize); // Start at begining of L1 table
Addr < BaseAdr + Size;
Addr += L1TableSize) // Increment by 1 L1 table
{
GMM_GFX_ADDRESS L1GfxAddress, L2GfxAddress;
GMM_GFX_ADDRESS L1CPUAddress, L2CPUAddress;
GMM_GFX_ADDRESS StartAddress = 0;
GMM_GFX_ADDRESS EndAddress = 0;
GMM_GFX_ADDRESS TileAddr = 0;
GMM_GFX_SIZE_T L2eIdx = 0;
StartAddress = Addr < BaseAdr ? BaseAdr : Addr;
EndAddress = Addr + L1TableSize;
if(EndAddress > BaseAdr + Size)
{
EndAddress = BaseAdr + Size;
}
GetL1L2TableAddr(StartAddress,
&L1GfxAddress,
&L2GfxAddress);
// If tables are not there, then they are already invalidated as part of
// AUX-TT initialization or other APIs.
if(L2GfxAddress == GMM_NO_TABLE ||
L1GfxAddress == GMM_NO_TABLE)
{
//Clear Valid-bit for L3Entry or L2Entry
uint64_t Data = 0;
GMM_GFX_ADDRESS TableGfxAddress = (L2GfxAddress == GMM_NO_TABLE) ? L3GfxAddress : L2GfxAddress;
GMM_GFX_ADDRESS TableCPUAddress = (L2GfxAddress == GMM_NO_TABLE) ? TTL3.CPUAddress : pTTL2[GMM_L3_ENTRY_IDX(AUXTT, StartAddress)].GetCPUAddress();
uint32_t TableEntryIdx = (L2GfxAddress == GMM_NO_TABLE) ? static_cast<uint32_t>(GMM_L3_ENTRY_IDX(AUXTT, StartAddress)) : static_cast<uint32_t>(GMM_L2_ENTRY_IDX(AUXTT, StartAddress));
L2CPUAddress = (L2GfxAddress == GMM_NO_TABLE) ? 0 : TableCPUAddress;
if(!NullL1Table || !NullL2Table)
{
AllocateDummyTables(&NullL2Table, &NullL1Table);
if(!NullL1Table || !NullL2Table)
{
//report error
LeaveCriticalSection(&TTLock);
return GMM_OUT_OF_MEMORY;
}
else
{
//Initialize dummy table entries (one-time)
GMM_GFX_ADDRESS TableAddr = NullL2Table->GetCPUAddress();
GMM_AUXTTL2e L2e = {0};
L2e.Valid = 1;
L2e.L1GfxAddr = (NullL1Table->GetPool()->GetGfxAddress() + PAGE_SIZE * NullL1Table->GetNodeIdx()) >> 13;
for(int i = 0; i < GMM_AUX_L2_SIZE; i++)
{
//initialize L2e ie clear Valid bit for all entries
((GMM_AUXTTL2e *)TableAddr)[i].Value = L2e.Value;
}
TableAddr = NullL1Table->GetCPUAddress();
GMM_AUXTTL1e L1e = {0};
L1e.Valid = 1;
L1e.GfxAddress = (NullCCSTile >> 8);
for(int i = 0; i < GMM_AUX_L1_SIZE(GetGmmLibContext()); i++)
{
//initialize L1e with null ccs tile
((GMM_AUXTTL1e *)TableAddr)[i].Value = L1e.Value;
}
}
}
if(L2GfxAddress == GMM_NO_TABLE)
{
GMM_AUXTTL3e L3e = {0};
L3e.Valid = 1;
L3e.L2GfxAddr = (NullL2Table->GetPool()->GetGfxAddress() + PAGE_SIZE * NullL2Table->GetNodeIdx()) >> 15;
Data = L3e.Value;
}
else
{
GMM_AUXTTL2e L2e = {0};
L2e.Valid = 1;
L2e.L1GfxAddr = (NullL1Table->GetPool()->GetGfxAddress() + PAGE_SIZE * NullL1Table->GetNodeIdx()) >> 13;
Data = L2e.Value;
}
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL2e *)TableCPUAddress)[TableEntryIdx].Value = Data;
}
else
{
if(L2GfxAddress != GMM_NO_TABLE)
{
pTTL2[GMM_L3_ENTRY_IDX(AUXTT, StartAddress)].UpdatePoolFence(UmdContext, false);
}
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
TableGfxAddress + TableEntryIdx * GMM_AUX_L2e_SIZE,
Data);
}
continue;
}
else
{
uint32_t L3eIdx = static_cast<uint32_t>(GMM_L3_ENTRY_IDX(AUXTT, StartAddress));
L2CPUAddress = pTTL2[L3eIdx].GetCPUAddress();
L2eIdx = GMM_L2_ENTRY_IDX(AUXTT, StartAddress);
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL3e *)(TTL3.CPUAddress))[L3eIdx].Valid = 1; //set Valid bit
((GMM_AUXTTL3e *)(TTL3.CPUAddress))[L3eIdx].L2GfxAddr = L2GfxAddress >> 15;
((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].Valid = 1; //set Valid bit
((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].L1GfxAddr = L1GfxAddress >> 13;
}
else
{
GMM_AUXTTL3e L3e = {0};
L3e.Valid = 1;
L3e.L2GfxAddr = L2GfxAddress >> 15;
PageTableMgr->TTCb.pfWriteL2L3Entry(
UmdContext->pCommandQueueHandle,
L3GfxAddress + (L3eIdx * GMM_AUX_L3e_SIZE),
L3e.Value);
pTTL2[L3eIdx].UpdatePoolFence(UmdContext, false);
GMM_AUXTTL2e L2e = {0};
L2e.Valid = 1;
L2e.L1GfxAddr = L1GfxAddress >> 13;
PageTableMgr->TTCb.pfWriteL2L3Entry(
UmdContext->pCommandQueueHandle,
L2GfxAddress + (L2eIdx * GMM_AUX_L2e_SIZE),
L2e.Value);
}
}
// For each 64KB or 16KB of main surface (entry) in L1 table
for(TileAddr = StartAddress;
TileAddr < EndAddress;
TileAddr += (!WA16K(GetGmmLibContext()) ? GMM_KBYTE(64) : GMM_KBYTE(16)))
{
uint64_t Data = PartialL1e | NullCCSTile | __BIT(0);
GMM_GFX_SIZE_T L1eIdx = GMM_L1_ENTRY_IDX(AUXTT, TileAddr, GetGmmLibContext());
GmmLib::LastLevelTable *pL1Tbl = NULL;
pL1Tbl = pTTL2[GMM_AUX_L3_ENTRY_IDX(TileAddr)].GetL1Table(L2eIdx, NULL);
L1CPUAddress = pL1Tbl->GetCPUAddress();
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL1e *)L1CPUAddress)[L1eIdx].Value = Data;
GMM_DPF(GFXDBG_NORMAL, "Null-Map | Table Entry: [0x%06x] L2Addr[0x%016llX] Value[0x%016llX] :: [0x%06x] L1Addr[0x%016llX] Value[0x%016llX]\n", L2eIdx, ((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx], ((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].L1GfxAddr << 13, L1eIdx, &((GMM_AUXTTL1e *)L1CPUAddress)[L1eIdx], Data);
}
else
{
pL1Tbl->UpdatePoolFence(UmdContext, false);
/* PageTableMgr->TTCb.pfWriteL1Entries(
UmdContext->pCommandQueueHandle,
2,
L1GfxAddress + (L1eIdx * GMM_AUX_L1e_SIZE),
(uint32_t*)(&Data));*/ //**********REQUIRE UMD CHANGE TO UPDATE 64-bit ENTRY - both DWORDs must be updated atomically*******/
PageTableMgr->TTCb.pfWriteL2L3Entry(
UmdContext->pCommandQueueHandle,
L1GfxAddress + (L1eIdx * GMM_AUX_L1e_SIZE),
Data);
}
if(pL1Tbl->TrackTableUsage(AUXTT, true, TileAddr, true, GetGmmLibContext()))
{ // L1 Table is not being used anymore
GMM_AUXTTL2e L2e = {0};
GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
GmmLib::LastLevelTable * pL1Tbl = NULL, *Prev = NULL;
pL1Tbl = pTTL2[GMM_L3_ENTRY_IDX(AUXTT, TileAddr)].GetL1Table(L2eIdx, &Prev);
// Map L2-entry to Null-L1Table
L2e.Valid = 1;
L2e.L1GfxAddr = (NullL1Table->GetPool()->GetGfxAddress() + PAGE_SIZE * NullL1Table->GetNodeIdx()) >> 13;
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].Value = L2e.Value;
}
else
{
pTTL2[GMM_L3_ENTRY_IDX(AUXTT, TileAddr)].UpdatePoolFence(UmdContext, false);
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
L2GfxAddress + L2eIdx * GMM_AUX_L2e_SIZE,
L2e.Value);
}
//Update usage for PoolNode assigned to L1Table, and free L1Tbl
if(pL1Tbl)
{
PoolElem = pL1Tbl->GetPool();
if(PoolElem)
{
if(pL1Tbl->GetBBInfo().BBQueueHandle)
{
PoolElem->GetNodeBBInfoAtIndex(pL1Tbl->GetNodeIdx()) = pL1Tbl->GetBBInfo();
}
DEASSIGN_POOLNODE(PageTableMgr, UmdContext, PoolElem, pL1Tbl->GetNodeIdx(), AUX_L1TABLE_SIZE_IN_POOLNODES)
}
pTTL2[GMM_L3_ENTRY_IDX(AUXTT, TileAddr)].DeleteFromList(pL1Tbl, Prev);
}
// The L1 table is unused -- meaning everything else in this table is
// already invalid. So, break early.
break;
}
}
}
if(!DoNotWait)
{
PageTableMgr->TTCb.pfEpilogTranslationTable(
UmdContext->pCommandQueueHandle,
1); // ForceFlush
}
LeaveCriticalSection(&TTLock);
return Status;
}
//=============================================================================
//
// Function: InvalidateTable (InvalidateMappings)
//
// Desc: Unmaps given resource from Aux Table; and marks affected entries as invalid
//
// Caller: UpdateAuxTable (unmap op)
//
// Parameters:
// UmdContext: Caller-thread specific info (regarding BB for Aux udpate, cmdQ to use etc)
// BaseAdr: Start adr of main surface
// Size: Main-surface size in bytes? (or take GmmResInfo?)
// DoNotWait: 1 for CPU update, 0 for async(Gpu) update
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::AuxTable::InvalidateTable(GMM_UMD_SYNCCONTEXT *UmdContext, GMM_GFX_ADDRESS BaseAdr, GMM_GFX_SIZE_T Size, uint8_t DoNotWait)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_GFX_SIZE_T L1TableSize = (GMM_L1_SIZE(AUXTT, GetGmmLibContext())) * (!WA16K(GetGmmLibContext()) ? GMM_KBYTE(64) : GMM_KBYTE(16)); //Each AuxTable entry maps 16K main-surface
GMM_GFX_ADDRESS Addr = 0;
GMM_GFX_ADDRESS L3GfxAddress = 0;
uint8_t isTRVA = 0;
GMM_CLIENT ClientType;
GET_GMM_CLIENT_TYPE(pClientContext, ClientType);
//NullCCSTile isn't initialized, disable TRVA path
isTRVA = (NullCCSTile ? isTRVA : 0);
EnterCriticalSection(&TTLock);
DoNotWait |= (!UmdContext || !UmdContext->pCommandQueueHandle);
if(TTL3.L3Handle)
{
L3GfxAddress = TTL3.GfxAddress;
}
else
{
LeaveCriticalSection(&TTLock);
return GMM_ERROR;
}
if(!DoNotWait)
{
PageTableMgr->TTCb.pfPrologTranslationTable(
UmdContext->pCommandQueueHandle);
}
// For each L1 table
for(Addr = GFX_ALIGN_FLOOR(BaseAdr, L1TableSize); // Start at begining of L1 table
Addr < BaseAdr + Size;
Addr += L1TableSize) // Increment by 1 L1 table
{
GMM_GFX_ADDRESS L1GfxAddress, L2GfxAddress;
GMM_GFX_ADDRESS L1CPUAddress, L2CPUAddress;
GMM_GFX_ADDRESS StartAddress = 0;
GMM_GFX_ADDRESS EndAddress = 0;
GMM_GFX_ADDRESS TileAddr = 0;
GMM_GFX_SIZE_T L2eIdx = 0;
StartAddress = Addr < BaseAdr ? BaseAdr : Addr;
EndAddress = Addr + L1TableSize;
if(EndAddress > BaseAdr + Size)
{
EndAddress = BaseAdr + Size;
}
GetL1L2TableAddr(StartAddress,
&L1GfxAddress,
&L2GfxAddress);
// If tables are not there, then they are already invalidated as part of
// AUX-TT initialization or other APIs.
if(L2GfxAddress == GMM_NO_TABLE ||
L1GfxAddress == GMM_NO_TABLE)
{
//Clear Valid-bit for L3Entry or L2Entry
GMM_AUXTTL2e L2e = {0}; //AUXTT L3e is identical to L2e, reuse.
GMM_GFX_ADDRESS TableGfxAddress = (L2GfxAddress == GMM_NO_TABLE) ? L3GfxAddress : L2GfxAddress;
GMM_GFX_ADDRESS TableCPUAddress = (L2GfxAddress == GMM_NO_TABLE) ? TTL3.CPUAddress : pTTL2[GMM_L3_ENTRY_IDX(AUXTT, StartAddress)].GetCPUAddress();
uint32_t TableEntryIdx = (L2GfxAddress == GMM_NO_TABLE) ? static_cast<uint32_t>(GMM_L3_ENTRY_IDX(AUXTT, StartAddress)) : static_cast<uint32_t>(GMM_L2_ENTRY_IDX(AUXTT, StartAddress));
L2CPUAddress = (L2GfxAddress == GMM_NO_TABLE) ? 0 : TableCPUAddress;
if(isTRVA && NullL2Table && NullL1Table)
{
//invalidate if request spans entire stretch ie TileAdr aligns L1TableSize*GMM_L2_SIZE
uint64_t Data = 0;
if(L2GfxAddress == GMM_NO_TABLE)
{
GMM_AUXTTL3e L3e = {0};
L3e.Valid = 1;
L3e.L2GfxAddr = (NullL2Table->GetPool()->GetGfxAddress() + PAGE_SIZE * NullL2Table->GetNodeIdx()) >> 15;
Data = L3e.Value;
}
else
{
GMM_AUXTTL2e L2e = {0};
L2e.Valid = 1;
L2e.L1GfxAddr = (NullL1Table->GetPool()->GetGfxAddress() + PAGE_SIZE * NullL1Table->GetNodeIdx()) >> 13;
Data = L2e.Value;
}
L2e.Value = Data;
}
else
{
L2e.Valid = 0;
}
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL2e *)TableCPUAddress)[TableEntryIdx].Value = L2e.Value;
}
else
{
if(L2GfxAddress != GMM_NO_TABLE)
{
pTTL2[GMM_L3_ENTRY_IDX(AUXTT, StartAddress)].UpdatePoolFence(UmdContext, false);
}
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
TableGfxAddress + TableEntryIdx * GMM_AUX_L2e_SIZE,
L2e.Value);
}
continue;
}
else
{
uint32_t L3eIdx = static_cast<uint32_t>(GMM_L3_ENTRY_IDX(AUXTT, StartAddress));
L2CPUAddress = pTTL2[L3eIdx].GetCPUAddress();
L2eIdx = GMM_L2_ENTRY_IDX(AUXTT, StartAddress);
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL3e *)(TTL3.CPUAddress))[L3eIdx].Valid = 1; //set Valid bit
((GMM_AUXTTL3e *)(TTL3.CPUAddress))[L3eIdx].L2GfxAddr = L2GfxAddress >> 15;
((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].Valid = 1; //set Valid bit
((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].L1GfxAddr = L1GfxAddress >> 13;
}
else
{
GMM_AUXTTL3e L3e = {0};
L3e.Valid = 1;
L3e.L2GfxAddr = L2GfxAddress >> 15;
PageTableMgr->TTCb.pfWriteL2L3Entry(
UmdContext->pCommandQueueHandle,
L3GfxAddress + (L3eIdx * GMM_AUX_L3e_SIZE),
L3e.Value);
pTTL2[L3eIdx].UpdatePoolFence(UmdContext, false);
GMM_AUXTTL2e L2e = {0};
L2e.Valid = 1;
L2e.L1GfxAddr = L1GfxAddress >> 13;
PageTableMgr->TTCb.pfWriteL2L3Entry(
UmdContext->pCommandQueueHandle,
L2GfxAddress + (L2eIdx * GMM_AUX_L2e_SIZE),
L2e.Value);
}
}
// For each 64KB or 16KB of main surface (entry) in L1 table
for(TileAddr = StartAddress;
TileAddr < EndAddress;
TileAddr += (!WA16K(GetGmmLibContext()) ? GMM_KBYTE(64) : GMM_KBYTE(16)))
{
//Invalidation of requested range irrespective of TRVA
uint64_t Data = GMM_INVALID_AUX_ENTRY;
GMM_GFX_SIZE_T L1eIdx = GMM_L1_ENTRY_IDX(AUXTT, TileAddr, GetGmmLibContext());
GmmLib::LastLevelTable *pL1Tbl = NULL;
pL1Tbl = pTTL2[GMM_AUX_L3_ENTRY_IDX(TileAddr)].GetL1Table(L2eIdx, NULL);
L1CPUAddress = pL1Tbl->GetCPUAddress();
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL1e *)L1CPUAddress)[L1eIdx].Value = Data;
GMM_DPF(GFXDBG_NORMAL, "UnMap | Table Entry: [0x%06x] L2Addr[0x%016llX] Value[0x%016llX] :: [0x%06x] L1Addr[0x%016llX] Value[0x%016llX]\n", L2eIdx, ((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx], ((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].L1GfxAddr << 13, L1eIdx, &((GMM_AUXTTL1e *)L1CPUAddress)[L1eIdx], Data);
}
else
{
pL1Tbl->UpdatePoolFence(UmdContext, false);
/* PageTableMgr->TTCb.pfWriteL1Entries(
UmdContext->pCommandQueueHandle,
2,
L1GfxAddress + (L1eIdx * GMM_AUX_L1e_SIZE),
(uint32_t*)(&Data));*/ //**********REQUIRE UMD CHANGE TO UPDATE 64-bit ENTRY - both DWORDs must be updated atomically*******/
PageTableMgr->TTCb.pfWriteL2L3Entry(
UmdContext->pCommandQueueHandle,
L1GfxAddress + (L1eIdx * GMM_AUX_L1e_SIZE),
Data);
}
if(pL1Tbl->TrackTableUsage(AUXTT, true, TileAddr, true, GetGmmLibContext()))
{ // L1 Table is not being used anymore
GMM_AUXTTL2e L2e = {0};
GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
GmmLib::LastLevelTable * pL1Tbl = NULL, *Prev = NULL;
pL1Tbl = pTTL2[GMM_L3_ENTRY_IDX(AUXTT, TileAddr)].GetL1Table(L2eIdx, &Prev);
if(isTRVA && NullL1Table &&
((TileAddr > GFX_ALIGN_FLOOR(BaseAdr, L1TableSize) && TileAddr < GFX_ALIGN_NP2(BaseAdr, L1TableSize)) ||
(TileAddr > GFX_ALIGN_FLOOR(BaseAdr + Size, L1TableSize) && TileAddr < GFX_ALIGN_NP2(BaseAdr + Size, L1TableSize))))
{
//Invalidation affects entries out of requested range, null-map for TR
L2e.Valid = 1;
L2e.L1GfxAddr = (NullL1Table->GetPool()->GetGfxAddress() + PAGE_SIZE * NullL1Table->GetNodeIdx()) >> 13;
}
else
{
// Clear valid bit of L2 entry
L2e.Valid = 0;
((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].Valid = 0;
}
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL2e *)L2CPUAddress)[L2eIdx].Value = L2e.Value;
}
else
{
pTTL2[GMM_L3_ENTRY_IDX(AUXTT, TileAddr)].UpdatePoolFence(UmdContext, false);
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
L2GfxAddress + L2eIdx * GMM_AUX_L2e_SIZE,
L2e.Value);
}
//Update usage for PoolNode assigned to L1Table, and free L1Tbl
if(pL1Tbl)
{
PoolElem = pL1Tbl->GetPool();
if(PoolElem)
{
if(pL1Tbl->GetBBInfo().BBQueueHandle)
{
PoolElem->GetNodeBBInfoAtIndex(pL1Tbl->GetNodeIdx()) = pL1Tbl->GetBBInfo();
}
DEASSIGN_POOLNODE(PageTableMgr, UmdContext, PoolElem, pL1Tbl->GetNodeIdx(), AUX_L1TABLE_SIZE_IN_POOLNODES)
}
pTTL2[GMM_L3_ENTRY_IDX(AUXTT, TileAddr)].DeleteFromList(pL1Tbl, Prev);
}
// The L1 table is unused -- meaning everything else in this table is
// already invalid. So, break early.
break;
}
}
}
if(!DoNotWait)
{
PageTableMgr->TTCb.pfEpilogTranslationTable(
UmdContext->pCommandQueueHandle,
1); // ForceFlush
}
LeaveCriticalSection(&TTLock);
return Status;
}
//=============================================================================
//
// Function: MapValidEntry
//
// Desc: Maps given main-surface, on Aux-Table, to get the exact CCS cacheline tied to
// different 4x4K pages of main-surface
//
// Caller: UpdateAuxTable (map op)
//
// Parameters:
// UmdContext: ptr to thread-data
// BaseAdr: Start adr of main-surface
// BaseSize: main-surface Size in bytes
// BaseResInfo: main surface ResInfo
// AuxVA: Start adr of Aux-surface
// AuxResInfo: Aux surface ResInfo
// PartialData: Aux L1 partial data (ie w/o address)
// DoNotWait: true for CPU update, false for async(Gpu) update
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::AuxTable::MapValidEntry(GMM_UMD_SYNCCONTEXT *UmdContext, GMM_GFX_ADDRESS BaseAdr, GMM_GFX_SIZE_T BaseSize,
GMM_RESOURCE_INFO *BaseResInfo, GMM_GFX_ADDRESS AuxVA, GMM_RESOURCE_INFO *AuxResInfo, uint64_t PartialData, uint8_t DoNotWait)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_GFX_ADDRESS Addr = 0, L3TableAdr = GMM_NO_TABLE;
GMM_GFX_SIZE_T L1TableSize = GMM_AUX_L1_SIZE(GetGmmLibContext()) * (!WA16K(GetGmmLibContext()) ? GMM_KBYTE(64) : GMM_KBYTE(16));
GMM_GFX_SIZE_T CCS$Adr = AuxVA;
uint8_t isTRVA =0 ;
GMM_CLIENT ClientType;
GET_GMM_CLIENT_TYPE(pClientContext, ClientType);
//NullCCSTile isn't initialized, disable TRVA path
isTRVA = (NullCCSTile ? isTRVA : 0);
EnterCriticalSection(&TTLock);
if(!TTL3.L3Handle || (!DoNotWait && !UmdContext))
{
Status = GMM_ERROR;
}
else
{
L3TableAdr = TTL3.GfxAddress;
if(!DoNotWait)
{
PageTableMgr->TTCb.pfPrologTranslationTable(UmdContext->pCommandQueueHandle);
}
GMM_DPF(GFXDBG_NORMAL, "Mapping surface: GPUVA=0x%016llX Size=0x%08X Aux_GPUVA=0x%016llX\n", BaseAdr, BaseSize, AuxVA);
for(Addr = GFX_ALIGN_FLOOR(BaseAdr, L1TableSize); Addr < BaseAdr + BaseSize; Addr += L1TableSize)
{
GMM_GFX_ADDRESS StartAdr, EndAdr, TileAdr;
GMM_GFX_ADDRESS L1TableAdr = GMM_NO_TABLE, L2TableAdr = GMM_NO_TABLE;
GMM_GFX_ADDRESS L1TableCPUAdr = GMM_NO_TABLE, L2TableCPUAdr = GMM_NO_TABLE;
GMM_GFX_SIZE_T L2eIdx = 0;
GMM_GFX_SIZE_T L3eIdx = 0;
bool AllocateL1 = false, AllocateL2 = false;
EndAdr = Addr + L1TableSize;
EndAdr = EndAdr > BaseAdr + BaseSize ? BaseAdr + BaseSize : EndAdr;
StartAdr = Addr < BaseAdr ? BaseAdr : Addr;
L2eIdx = GMM_L2_ENTRY_IDX(AUXTT, StartAdr);
L3eIdx = GMM_L3_ENTRY_IDX(AUXTT, StartAdr);
//Allocate L2/L1 Table -- get L2 Table Adr for <StartAdr,EndAdr>
GetL1L2TableAddr(Addr, &L1TableAdr, &L2TableAdr);
if(L2TableAdr == GMM_NO_TABLE || L1TableAdr == GMM_NO_TABLE)
{
AllocateL1 = GMM_NO_TABLE == L1TableAdr;
AllocateL2 = GMM_NO_TABLE == L2TableAdr;
AllocateL1L2Table(Addr, &L1TableAdr, &L2TableAdr);
if(L2TableAdr == GMM_NO_TABLE || L1TableAdr == GMM_NO_TABLE)
{
LeaveCriticalSection(&TTLock);
return GMM_OUT_OF_MEMORY;
}
if(AllocateL2)
{
uint32_t i = 0;
GMM_AUXTTL2e InvalidEntry;
InvalidEntry.Value = 0;
if(isTRVA && NullL1Table)
{
InvalidEntry.Valid = 1;
InvalidEntry.L1GfxAddr = (NullL1Table->GetPool()->GetGfxAddress() + PAGE_SIZE * NullL1Table->GetNodeIdx()) >> 13;
}
if(DoNotWait)
{
L2TableCPUAdr = pTTL2[L3eIdx].GetCPUAddress();
((GMM_AUXTTL3e *)(TTL3.CPUAddress))[L3eIdx].Value = 0;
((GMM_AUXTTL3e *)(TTL3.CPUAddress))[L3eIdx].L2GfxAddr = L2TableAdr >> 15;
((GMM_AUXTTL3e *)(TTL3.CPUAddress))[L3eIdx].Valid = 1;
for(i = 0; i < GMM_AUX_L2_SIZE; i++)
{
//initialize L2e ie clear Valid bit for all entries
((GMM_AUXTTL2e *)L2TableCPUAdr)[i].Value = InvalidEntry.Value;
}
}
else
{
GMM_AUXTTL3e L3e = {0};
L3e.Valid = 1;
L3e.L2GfxAddr = L2TableAdr >> 15;
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
L3TableAdr + L3eIdx * GMM_AUX_L3e_SIZE,
L3e.Value);
//initialize L2e ie clear valid bit for all entries
for(i = 0; i < GMM_AUX_L2_SIZE; i++)
{
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
L2TableAdr + i * GMM_AUX_L2e_SIZE,
InvalidEntry.Value);
}
}
}
if(AllocateL1)
{
uint64_t InvalidEntry = (!isTRVA) ? GMM_INVALID_AUX_ENTRY : (NullCCSTile | __BIT(0));
uint32_t i = 0;
if(DoNotWait)
{
GmmLib::LastLevelTable *pL1Tbl = NULL;
pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx, NULL);
L2TableCPUAdr = pTTL2[L3eIdx].GetCPUAddress();
L1TableCPUAdr = pL1Tbl->GetCPUAddress();
//Sync update on CPU
((GMM_AUXTTL2e *)L2TableCPUAdr)[L2eIdx].Value = 0;
((GMM_AUXTTL2e *)L2TableCPUAdr)[L2eIdx].L1GfxAddr = L1TableAdr >> 13;
((GMM_AUXTTL2e *)L2TableCPUAdr)[L2eIdx].Valid = 1;
for(i = 0; i < (uint32_t)GMM_AUX_L1_SIZE(GetGmmLibContext()); i++)
{
//initialize L1e ie mark all entries with Null tile value
((GMM_AUXTTL1e *)L1TableCPUAdr)[i].Value = InvalidEntry;
}
}
else
{
GMM_AUXTTL2e L2e = {0};
L2e.Valid = 1;
L2e.L1GfxAddr = L1TableAdr >> 13;
pTTL2[L3eIdx].UpdatePoolFence(UmdContext, false);
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
L2TableAdr + L2eIdx * GMM_AUX_L2e_SIZE,
L2e.Value);
//initialize all L1e with invalid entries
for(i = 0; i < (uint32_t)GMM_AUX_L1_SIZE(GetGmmLibContext()); i++)
{
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
L1TableAdr + i * sizeof(uint64_t),
InvalidEntry);
}
}
}
}
GMM_DPF(GFXDBG_NORMAL, "Mapping surface: GPUVA=0x%016llx Size=0x%08x Aux_GPUVA=0x%016llx", StartAdr, BaseSize, CCS$Adr);
for(TileAdr = StartAdr; TileAdr < EndAdr; TileAdr += (!WA16K(pClientContext->GetLibContext()) ? GMM_KBYTE(64) : GMM_KBYTE(16)),
CCS$Adr += (pClientContext->GetLibContext()->GetSkuTable().FtrLinearCCS ?
(!WA16K(pClientContext->GetLibContext()) ? GMM_BYTES(256) : GMM_BYTES(64)) :
0))
{
GMM_GFX_SIZE_T L1eIdx = GMM_L1_ENTRY_IDX(AUXTT, TileAdr, GetGmmLibContext());
GMM_AUXTTL1e L1e = {0};
L1e.Value = PartialData;
L1e.Valid = 1;
CCS$Adr = (pClientContext->GetLibContext()->GetSkuTable().FtrLinearCCS ? CCS$Adr :
__GetCCSCacheline(BaseResInfo, BaseAdr, AuxResInfo, AuxVA, TileAdr - BaseAdr));
if(!WA16K(GetGmmLibContext()))
{
__GMM_ASSERT((CCS$Adr & 0xFF) == 0x0);
__GMM_ASSERT(GFX_IS_ALIGNED(CCS$Adr, GMM_BYTES(256)));
__GMM_ASSERT(GFX_IS_ALIGNED(TileAdr, GMM_KBYTE(64)));
L1e.GfxAddress = CCS$Adr >> 8; /*********** 256B-aligned CCS adr *****/
}
else
{
L1e.Reserved2 = CCS$Adr >> 6; /*********** 2 lsbs of 64B-aligned CCS adr *****/
L1e.GfxAddress = CCS$Adr >> 8; /*********** 256B-aligned CCS adr *****/
}
//GMM_DPF(GFXDBG_CRITICAL, "Map | L1=0x%016llx[0x%016llx] L1e=[0x%016llx] | [ GPUVA=0x%016llx[0x%08x] Aux_GPUVA=0x%016llx [%s]", L1TableAdr + L1eIdx << 3, L1eIdx << 3, L1e.Value, TileAdr, TileAdr - StartAdr, CCS$Adr, L1e.Valid ? "V" : " ");
GmmLib::LastLevelTable *pL1Tbl = NULL;
pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx, NULL);
L1TableCPUAdr = pL1Tbl->GetCPUAddress();
if(DoNotWait)
{
//Sync update on CPU
((GMM_AUXTTL1e *)L1TableCPUAdr)[L1eIdx].Value = L1e.Value;
//GMM_DPF(GFXDBG_CRITICAL, "Map | Table Entry: [0x%06x] L2Addr[0x%016llX] Value[0x%016llX] :: [0x%06x] L1Addr[0x%016llX] Value[0x%016llX] -> GPUVA: 0x%016llX[0x%06X] Aux_GPUVA: 0x%016llX [%s]\n", L2eIdx, &((GMM_AUXTTL2e *)L2TableCPUAdr)[L2eIdx], ((GMM_AUXTTL2e *)L2TableCPUAdr)[L2eIdx].L1GfxAddr << 13, L1eIdx, &((GMM_AUXTTL1e *)L1TableCPUAdr)[L1eIdx] /*L1TableAdr + L1eIdx * GMM_AUX_L1e_SIZE*/, L1e.Value, TileAdr, TileAdr - BaseAdr, ((GMM_AUXTTL1e *)L1TableCPUAdr)[L1eIdx].GfxAddress << 6, ((GMM_AUXTTL1e *)L1CPUAdr)[L1eIdx].Valid ? "V" : " ");
}
else
{
pL1Tbl->UpdatePoolFence(UmdContext, false);
PageTableMgr->TTCb.pfWriteL2L3Entry(UmdContext->pCommandQueueHandle,
L1TableAdr + L1eIdx * GMM_AUX_L1e_SIZE,
L1e.Value);
}
// Since we are mapping a non-null entry, no need to check whether
// L1 table is unused.
pL1Tbl->TrackTableUsage(AUXTT, true, TileAdr, false, GetGmmLibContext());
}
}
if(!DoNotWait)
{
PageTableMgr->TTCb.pfEpilogTranslationTable(
UmdContext->pCommandQueueHandle,
1);
}
}
LeaveCriticalSection(&TTLock);
return Status;
}
GMM_AUXTTL1e GmmLib::AuxTable::CreateAuxL1Data(GMM_RESOURCE_INFO *BaseResInfo)
{
GMM_FORMAT_ENTRY FormatInfo = pClientContext->GetLibContext()->GetPlatformInfo().FormatTable[BaseResInfo->GetResourceFormat()];
GMM_AUXTTL1e L1ePartial = {0};
#define GMM_REGISTRY_UMD_PATH "SOFTWARE\\Intel\\IGFX\\GMM\\"
#define GMM_E2EC_OVERRIDEDEPTH16BPPTO12 "ForceYUV16To12BPP"
L1ePartial.Mode = BaseResInfo->GetResFlags().Info.RenderCompressed ? 0x1 : 0x0; //MC on VCS supports all compression modes,
//MC on Render pipe only 128B compr (until B-step)
//Recognize which .MC surfaces needs Render pipe access
if(pClientContext->GetLibContext()->GetWaTable().WaLimit128BMediaCompr)
{
L1ePartial.Mode = 0x1; //Limit media compression to 128B (same as RC) on gen12LP A0
}
//L1ePartial.Lossy = 0; // when to set it
L1ePartial.TileMode = BaseResInfo->GetResFlags().Info.TiledYs ? 0 : 1;
L1ePartial.Format = FormatInfo.CompressionFormat.AuxL1eFormat;
L1ePartial.LumaChroma = GmmIsPlanar(BaseResInfo->GetResourceFormat());
if(pClientContext->GetLibContext()->GetWaTable().WaUntypedBufferCompression && BaseResInfo->GetResourceType() == RESOURCE_BUFFER)
{
//Gen12LP WA to support untyped raw buffer compression on HDC ie MLC(machine-learning compression)
L1ePartial.TileMode = 0;
L1ePartial.Depth = 0x6;
L1ePartial.Format = GMM_E2ECOMP_FORMAT_RGBAFLOAT16;
}
__GMM_ASSERT(L1ePartial.Format > GMM_E2ECOMP_MIN_FORMAT && //Are we going to reuse 0x00 for uncompressed indication? CCS contains that info, but only known by HW
L1ePartial.Format <= GMM_E2ECOMP_MAX_FORMAT); //Could SW use it as surface-wide uncompressed state indicator? If so, remove teh assert (Need to make sure, all format encodings are correct)
if(BaseResInfo->GetResFlags().Info.RenderCompressed)
{
if(BaseResInfo->GetResourceType() != RESOURCE_BUFFER)
{
switch(FormatInfo.Element.BitsPer)
{
case 8:
L1ePartial.Depth = 0x4;
break;
case 16:
L1ePartial.Depth = 0x0;
break;
case 32:
L1ePartial.Depth = 0x5;
break;
case 64:
L1ePartial.Depth = 0x6;
break;
case 128:
L1ePartial.Depth = 0x7;
break;
default:
L1ePartial.Depth = 0x3;
}
}
}
else
{
switch(BaseResInfo->GetResourceFormat())
{
case GMM_FORMAT_P012:
case GMM_FORMAT_Y412:
case GMM_FORMAT_Y212: //which format encoding for Y212, Y412, P012?
L1ePartial.Depth = 0x2;
break;
case GMM_FORMAT_P010:
//case GMM_FORMAT_Y410:
case GMM_FORMAT_Y210: //which format encoding for Y210?
L1ePartial.Depth = 0x1;
break;
case GMM_FORMAT_P016: //per HAS, separate encoding than P010, but a comment says to use P010 in AuxTable?
case GMM_FORMAT_Y416:
case GMM_FORMAT_Y216:
L1ePartial.Depth = 0x0;
break;
default:
L1ePartial.Depth = 0x3; //For MC, bpp got from format encoding
}
if(L1ePartial.Format == GMM_E2ECOMP_FORMAT_R10G10B10A2_UNORM)
{
L1ePartial.Format = GMM_E2ECOMP_FORMAT_RGB10b;
}
}
return L1ePartial;
}
GMM_GFX_ADDRESS GMM_INLINE GmmLib::AuxTable::__GetCCSCacheline(GMM_RESOURCE_INFO *BaseResInfo, GMM_GFX_ADDRESS BaseAdr,
GMM_RESOURCE_INFO *AuxResInfo, GMM_GFX_ADDRESS AuxVA, GMM_GFX_SIZE_T AdrOffset)
{
GMM_GFX_ADDRESS CCSChunkAdr = 0xFFFFFFF0;
uint32_t x = 0, y = 0;
uint32_t i = 0, j = 0;
uint32_t CCSXTile = 0, CCSYTile = 0;
GMM_UNREFERENCED_PARAMETER(BaseAdr);
bool BaseIsYF = BaseResInfo->GetResFlags().Info.TiledYf ? true : false;
uint32_t BasePitchInTiles = BaseResInfo->GetRenderPitchTiles();
//Find YF/YS TileId <x,y> for given main surface 16K-chunk
//and CCS$Id <i,j> corresponding to main's <x,y>
AdrOffset >>= 14; //AdrOffset must be 16K-aligned chunk, since mapping unit is 4 YF pages
if(BaseIsYF)
{
uint32_t PitchIn4YF = BasePitchInTiles / 4; //Base Pitch is physically padded to 4x1 YF width
i = static_cast<uint32_t>(AdrOffset % PitchIn4YF);
j = static_cast<uint32_t>(AdrOffset / PitchIn4YF);
}
else if(BasePitchInTiles != 0) //TileYs
{
x = static_cast<uint32_t>(AdrOffset >> 2); //YS-tile count
y = x / BasePitchInTiles; //YS- tile id <x,y>
x = x % BasePitchInTiles;
i = 2 * x;
j = 2 * y;
switch(AdrOffset % 4) //YS : XYXY [XYXY YF] ie 2x2 16K-units in Y-major
{
case 0:
break;
case 1:
j++;
break;
case 2:
i++;
break;
case 3:
i++;
j++;
break;
}
}
//Compute CCS$ address for <i,j>
CCSXTile = (i >= 8) ? i / 8 : 0; //8x8 CLs make one CCS Tile; get TileOffset
CCSYTile = (j >= 8) ? j / 8 : 0;
i %= 8;
j %= 8;
uint32_t AuxPitchInTiles = AuxResInfo ? AuxResInfo->GetRenderPitchTiles() : BaseResInfo->GetRenderAuxPitchTiles();
CCSChunkAdr = AuxVA + ((CCSXTile + CCSYTile * AuxPitchInTiles) * GMM_KBYTE(4)) + (8 * GMM_BYTES(64) * i) + (GMM_BYTES(64) * j);
return CCSChunkAdr;
}
#endif /*!__GMM_KMD__*/

View File

@ -0,0 +1,733 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Description: UMD-TT manager (manages both TR-TT and AUX-TT in user mode space)
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "External/Common/GmmPageTableMgr.h"
#include "../TranslationTable/GmmUmdTranslationTable.h"
#include "External/Common/GmmClientContext.h"
#if defined(__linux__)
#include "Internal/Linux/GmmResourceInfoLinInt.h"
#endif
#define ENTER_CRITICAL_SECTION \
if(AuxTTObj) \
{ \
EnterCriticalSection(&PoolLock); \
}
#define EXIT_CRITICAL_SECTION \
if(AuxTTObj) \
{ \
LeaveCriticalSection(&PoolLock); \
}
extern GMM_MA_LIB_CONTEXT *pGmmMALibContext;
#if defined(__linux__)
GMM_STATUS GmmLib::__GmmDeviceAlloc(GmmClientContext * pClientContext,
GMM_DEVICE_CALLBACKS_INT *pDeviceCbInt,
GMM_DEVICE_ALLOC * pAlloc)
{
GMM_CLIENT ClientType;
GMM_DDI_ALLOCATE Alloc = {0};
int err;
GET_GMM_CLIENT_TYPE(pClientContext, ClientType);
__GMM_ASSERTPTR(GmmCheckForNullDevCbPfn(ClientType, pDeviceCbInt, GMM_DEV_CB_ALLOC), GMM_INVALIDPARAM);
if(GmmCheckForNullDevCbPfn(ClientType, pDeviceCbInt, GMM_DEV_CB_ALLOC))
{
Alloc.size = pAlloc->Size;
Alloc.alignment = pAlloc->Alignment;
err = GmmDeviceCallback(ClientType, pDeviceCbInt, &Alloc);
if(err)
{
return GMM_OUT_OF_MEMORY;
}
pAlloc->GfxVA = Alloc.gfxAddr;
pAlloc->CPUVA = (GMM_GFX_ADDRESS) Alloc.cpuAddr;
pAlloc->Handle = (HANDLE)Alloc.bo;
}
return GMM_SUCCESS;
}
GMM_STATUS GmmLib::__GmmDeviceDealloc(GMM_CLIENT ClientType,
GMM_DEVICE_CALLBACKS_INT *DeviceCb,
GMM_DEVICE_DEALLOC * pDealloc,
GmmClientContext * pClientContext)
{
GMM_DDI_DEALLOCATE DeAlloc = {0};
int err = 0;
__GMM_ASSERTPTR(GmmCheckForNullDevCbPfn(ClientType, DeviceCb, GMM_DEV_CB_DEALLOC), GMM_INVALIDPARAM);
if(GmmCheckForNullDevCbPfn(ClientType, DeviceCb, GMM_DEV_CB_DEALLOC))
{
DeAlloc.bo = pDealloc->Handle;
err = GmmDeviceCallback(ClientType, DeviceCb, &DeAlloc);
}
return (err == 0) ? GMM_SUCCESS : GMM_ERROR;
}
#endif
//=============================================================================
//
// Function: __AllocateNodePool
//
// Desc: Allocates (always resident SVM) memory for new Pool node, and updates PageTableMgr object
//
// Parameters:
// AddrAlignment: Pool allocation address alignment
//
// Returns:
// S_OK on success,
//-----------------------------------------------------------------------------
GmmLib::GMM_PAGETABLEPool *GmmLib::GmmPageTableMgr::__AllocateNodePool(uint32_t AddrAlignment, GmmLib::POOL_TYPE Type)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_RESOURCE_INFO *pGmmResInfo = NULL;
GMM_PAGETABLEPool *pTTPool = NULL;
HANDLE PoolHnd = 0;
GMM_CLIENT ClientType;
GMM_DEVICE_ALLOC Alloc = {0};
ENTER_CRITICAL_SECTION
//Allocate pool, sized PAGETABLE_POOL_MAX_NODES pages, assignable to TR/Aux L1/L2 tables
//SVM allocation, always resident
Alloc.Size = PAGETABLE_POOL_SIZE;
Alloc.Alignment = AddrAlignment;
Alloc.hCsr = hCsr;
Status = __GmmDeviceAlloc(pClientContext, &DeviceCbInt, &Alloc);
if(Status != GMM_SUCCESS)
{
__GMM_ASSERT(0);
EXIT_CRITICAL_SECTION
return NULL;
}
PoolHnd = Alloc.Handle;
pGmmResInfo = (GMM_RESOURCE_INFO *)Alloc.Priv;
pTTPool = new GMM_PAGETABLEPool(PoolHnd, pGmmResInfo, Alloc.GfxVA, Alloc.CPUVA, Type);
if(pTTPool)
{
if(pPool)
{
NumNodePoolElements++;
if(Type == POOL_TYPE_TRTTL2) // TRTT-L2 not 1st node in Pool LinkedList, place it at beginning
{
pPool = pPool->InsertInListAtBegin(pTTPool);
}
else
{
pTTPool = pPool->InsertInList(pTTPool);
}
}
else
{
NumNodePoolElements = 1;
pPool = pTTPool;
}
}
else
{
__GMM_ASSERT(0);
Status = GMM_OUT_OF_MEMORY;
}
EXIT_CRITICAL_SECTION
return (Status == GMM_SUCCESS) ? pTTPool : NULL;
}
//=============================================================================
//
// Function: __ReleaseUnusedPool
//
// Desc: Frees up unused PageTablePools once residency limit is hit
//
// Parameters:
// UmdContext: pointer to caller thread's context (containing BBHandle/Fence info)
//
//-----------------------------------------------------------------------------
void GmmLib::GmmPageTableMgr::__ReleaseUnusedPool(GMM_UMD_SYNCCONTEXT *UmdContext)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_GFX_SIZE_T PoolSizeToFree = {0};
GMM_GFX_SIZE_T FreedSize = {0};
GmmLib::GMM_PAGETABLEPool *Pool = NULL, *PrevPool = NULL;
uint32_t i = 0;
GMM_CLIENT ClientType;
GMM_DEVICE_DEALLOC Dealloc;
GET_GMM_CLIENT_TYPE(pClientContext, ClientType);
ENTER_CRITICAL_SECTION
if(pPool->__IsUnusedTRTTPoolOverLimit(&PoolSizeToFree))
{
for(i = 0; i < NumNodePoolElements && FreedSize < PoolSizeToFree; i++)
{
Pool = (PrevPool) ? PrevPool->GetNextPool() : pPool;
if(Pool->IsPoolInUse(UmdContext ? SyncInfo(UmdContext->BBFenceObj, UmdContext->BBLastFence) : SyncInfo()))
{
PrevPool = Pool;
continue;
}
if(GmmCheckForNullDevCbPfn(ClientType, &DeviceCbInt, GMM_DEV_CB_WAIT_FROM_CPU))
{
GMM_DDI_WAITFORSYNCHRONIZATIONOBJECTFROMCPU Wait = {0};
Wait.bo = Pool->GetPoolHandle();
GmmDeviceCallback(ClientType, &DeviceCbInt, &Wait);
}
Dealloc.Handle = Pool->GetPoolHandle();
Dealloc.GfxVA = Pool->GetGfxAddress();
Dealloc.Priv = Pool->GetGmmResInfo();
Dealloc.hCsr = hCsr;
Status = __GmmDeviceDealloc(ClientType, &DeviceCbInt, &Dealloc, pClientContext);
__GMM_ASSERT(GMM_SUCCESS == Status);
if(PrevPool)
{
PrevPool->GetNextPool() = Pool->GetNextPool();
}
else
{
pPool = Pool->GetNextPool();
}
delete Pool;
FreedSize += PAGETABLE_POOL_SIZE;
}
}
EXIT_CRITICAL_SECTION
}
//=============================================================================
//
// Function: __GetFreePoolNode
//
// Desc: Finds free node within existing PageTablePool(s), if no such node found,
// allocates new PageTablePool. Caller should update Pool Node usage
//
// Parameters:
// FreePoolNodeIdx: pointer to return Pool's free Node index
// PoolType: AuxTT_L1/L2 pool
//
// Returns:
// PageTablePool element and FreePoolNodeIdx that should be used for L2/L1 assignment
// NULL, if no free node exists and new pool allocation failed
//-----------------------------------------------------------------------------
GmmLib::GMM_PAGETABLEPool *GmmLib::GmmPageTableMgr::__GetFreePoolNode(uint32_t *FreePoolNodeIdx, POOL_TYPE PoolType)
{
uint32_t PoolNode = -1, i = 0, j = 0, DWdivisor = 1, IdxMultiplier = 1;
bool PoolNodeFound = false, TRTTPool = false;
ENTER_CRITICAL_SECTION
GmmLib::GMM_PAGETABLEPool *Pool = pPool;
Pool = (PoolType == POOL_TYPE_TRTTL2) ? Pool : //1st pool reserved for TRTT-L2, since TRTT-L2 pruning not supported yet,
(Pool ? Pool->GetNextPool() : NULL); //other pools can be TR-L1/Aux-L1/Aux-L2 (and support dynamic pruning)
TRTTPool = (PoolType == POOL_TYPE_TRTTL2 || PoolType == POOL_TYPE_TRTTL1) ? true : false;
DWdivisor = TRTTPool ? 8 * sizeof(uint32_t) : (PoolType == POOL_TYPE_AUXTTL2) ? 8 * sizeof(uint32_t) * AUX_L2TABLE_SIZE_IN_POOLNODES : 8 * sizeof(uint32_t) * AUX_L1TABLE_SIZE_IN_POOLNODES;
IdxMultiplier = TRTTPool ? 1 : (PoolType == POOL_TYPE_AUXTTL2) ? AUX_L2TABLE_SIZE_IN_POOLNODES : AUX_L1TABLE_SIZE_IN_POOLNODES;
//Scan existing PageTablePools for free pool node
for(i = (PoolType == POOL_TYPE_TRTTL2) ? 0 : 1; Pool && i < NumNodePoolElements; i++)
{
if(Pool->GetNumFreeNode() > 0 && Pool->GetPoolType() == PoolType)
{
PoolNodeFound = true;
*FreePoolNodeIdx = 0;
for(; j < PAGETABLE_POOL_MAX_NODES / DWdivisor; j++)
{
if(_BitScanForward((uint32_t *)&PoolNode, (uint32_t) ~(Pool->GetNodeUsageAtIndex(j)))) // Get LSB that has value 0
{
*FreePoolNodeIdx += PoolNode * IdxMultiplier;
PoolNodeFound = true;
break;
}
PoolNodeFound = false;
*FreePoolNodeIdx += DWdivisor; //DWORD size in bits
}
}
if(PoolNodeFound)
{
__GMM_ASSERT(Pool->GetPoolType() == PoolType);
EXIT_CRITICAL_SECTION
return Pool;
}
Pool = Pool->GetNextPool();
}
//No free pool node, allocate new
if(!PoolNodeFound)
{
GMM_PAGETABLEPool *Pool = NULL;
if(Pool = __AllocateNodePool(IdxMultiplier * PAGE_SIZE, PoolType))
{
__GMM_ASSERT(Pool->GetPoolType() == PoolType);
*FreePoolNodeIdx = 0;
EXIT_CRITICAL_SECTION
return Pool;
}
}
EXIT_CRITICAL_SECTION
return NULL;
}
/**********************************************************************************
** Class GmmPageTableMgr functions **
***********************************************************************************/
/////////////////////////////////////////////////////////////////////////////////////
/// Instantiates GmmPageTableMgr, allocating memory for root-tables, copies provided
/// device-callback function pointers
///
/// @param[in] DeviceCb: pointer sharing device-callback function pointers
/// @param[in] TTFlags: Flags specifying which PageTables are required by client
/// @return GmmPageTableMgr*
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::GmmPageTableMgr::GmmPageTableMgr(GMM_DEVICE_CALLBACKS_INT *DeviceCB, uint32_t TTFlags, GmmClientContext *pClientContextIn)
: GmmPageTableMgr()
{
GMM_PAGETABLE_MGR *ptr = NULL;
GMM_STATUS status = GMM_SUCCESS;
GMM_CLIENT ClientType;
if(pClientContextIn)
{
ClientType = pClientContextIn->GetClientType();
}
else
{
goto ERROR_CASE;
}
// this is needed if there is an error case and destructor gets called on ptr
this->pClientContext = pClientContextIn;
// Currently coping the code below to GMMOldAPi.cpp for backward compatible.
// Any changes here should be copied there.
//Initialize PageTableMgr further, only if PageTable creation succeeded
try
{
ptr = new GmmPageTableMgr();
ptr->pClientContext = pClientContextIn;
memcpy(&ptr->DeviceCbInt, DeviceCB, sizeof(GMM_DEVICE_CALLBACKS_INT));
if(pClientContextIn->GetSkuTable().FtrE2ECompression &&
!pClientContextIn->GetSkuTable().FtrFlatPhysCCS)
{
__GMM_ASSERT(TTFlags & AUXTT); //Aux-TT is mandatory
ptr->AuxTTObj = new AuxTable();
if(!ptr->AuxTTObj)
{
goto ERROR_CASE;
}
ptr->AuxTTObj->PageTableMgr = ptr;
ptr->AuxTTObj->pClientContext = pClientContextIn;
status = ptr->AuxTTObj->AllocateL3Table(8 * PAGE_SIZE, 8 * PAGE_SIZE);
if(status != GMM_SUCCESS)
{
InitializeCriticalSection(&(ptr->PoolLock));
goto ERROR_CASE;
}
}
}
catch(...)
{
__GMM_ASSERT(false);
if(ptr && (AuxTTObj))
{
InitializeCriticalSection(&(ptr->PoolLock));
}
goto ERROR_CASE;
}
if(status == GMM_SUCCESS && !(AuxTTObj))
{
if(ptr->AuxTTObj)
{
ptr->AuxTTObj->PageTableMgr = this;
}
*this = *ptr;
//Don't initialize PoolLock until any of AuxTable object created
if(ptr->AuxTTObj )
{
InitializeCriticalSection(&PoolLock);
}
//Delete temporary ptr, but don't release allocated PageTable Obj.
ptr->AuxTTObj = NULL;
}
ERROR_CASE:
delete ptr;
ptr = NULL;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns Root-table address for Aux-table
///
/// @return GMM_GFX_ADDRESS if Aux-Table was created; NULL otherwise
/////////////////////////////////////////////////////////////////////////////////////
GMM_GFX_ADDRESS GmmLib::GmmPageTableMgr::GetAuxL3TableAddr()
{
return AuxTTObj ? AuxTTObj->GetL3Address() : 0ULL;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Queues commands to initialize Aux-Table registers in the HW context image
///
/// @param[in] initialBBHandle: pointer to BatchBuffer for queuing commands
/// @param[in] engType: specifes engine on which the context would run
/// @return GMM_SUCCESS if queuing succeeded; GMM_ERROR otherwise
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmPageTableMgr::InitContextAuxTableRegister(HANDLE CmdQHandle, GMM_ENGINE_TYPE engType)
{
GMM_GFX_ADDRESS MaskedL3GfxAddress = 0ULL;
GMM_UNREFERENCED_PARAMETER(engType);
//Check FtrE2ECompression = 1
if(GetLibContext()->GetSkuTable().FtrE2ECompression && AuxTTObj != NULL)
{
EnterCriticalSection(&AuxTTObj->TTLock);
if(CmdQHandle)
{
//engType = ENGINE_TYPE_RCS; //use correct offset based on engType (once per-eng offsets known)
uint64_t RegOffset = 0, L3AdrReg = 0;
GET_L3ADROFFSET(0, L3AdrReg, GetLibContext());
RegOffset = (L3AdrReg + sizeof(uint32_t));
RegOffset = L3AdrReg | (RegOffset << 0x20);
MaskedL3GfxAddress = AuxTTObj->GetL3Address();
//TTCb.pfPrologTranslationTable(CmdQHandle); //MI_FLUSH, TLBInv not required since its called during context-init
TTCb.pfWriteL3Adr(CmdQHandle, MaskedL3GfxAddress, RegOffset);
GMM_DPF(GFXDBG_NORMAL, "AuxTT Map Address: GPUVA=0x%016llX\n", MaskedL3GfxAddress);
//TTCb.pfEpilogTranslationTable(CmdQHandle, 0);
AuxTTObj->GetRegisterStatus() = 0;
}
else
{
__GMM_ASSERT(false);
LeaveCriticalSection(&AuxTTObj->TTLock);
return GMM_INVALIDPARAM;
}
LeaveCriticalSection(&AuxTTObj->TTLock);
}
return GMM_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Updates the Aux-PageTables, for given base resource, with appropriate mappings
///
/// @param[in] Details of AuxTable update request
/// @return GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmPageTableMgr::UpdateAuxTable(const GMM_DDI_UPDATEAUXTABLE *UpdateReq)
{
if(GetAuxL3TableAddr() == 0ULL)
{
GMM_ASSERTDPF(0, "Invalid AuxTable update request, AuxTable is not initialized");
return GMM_INVALIDPARAM;
}
if(!((UpdateReq->BaseResInfo->GetResFlags().Info.RenderCompressed ||
UpdateReq->BaseResInfo->GetResFlags().Info.MediaCompressed) &&
((!UpdateReq->AuxResInfo && UpdateReq->BaseResInfo->GetResFlags().Gpu.UnifiedAuxSurface) ||
(UpdateReq->AuxResInfo && UpdateReq->AuxResInfo->GetResFlags().Gpu.CCS))))
/*(UpdateReq->BaseResInfo->GetResFlags().Gpu.TiledResource ||
UpdateReq->BaseResInfo->GetResFlags().Gpu.Depth) */
//Allow Separate Aux for Depth/TR/MSAA/others?
{
GMM_ASSERTDPF(0, "Invalid AuxTable update request");
return GMM_INVALIDPARAM;
}
if(UpdateReq->Map && !(!UpdateReq->BaseResInfo->GetResFlags().Gpu.TiledResource || (UpdateReq->BaseResInfo->GetResFlags().Gpu.TiledResource && UpdateReq->UmdContext && UpdateReq->UmdContext->pCommandQueueHandle)))
{
//GMM_DPF_CRITICAL("TiledResources must Gpu-update AuxTable, proceeding with CPU-update...");
//Allowing CPU-update if requested so..
if(!UpdateReq->DoNotWait)
{
return GMM_INVALIDPARAM;
}
}
ENTER_CRITICAL_SECTION
if(UpdateReq->Map)
{
//Get AuxL1e data (other than CCS-adr) from main surface
uint64_t PartialL1e = AuxTTObj->CreateAuxL1Data(UpdateReq->BaseResInfo).Value;
GMM_STATUS Status = GMM_SUCCESS;
if(UpdateReq->BaseResInfo->GetResFlags().Gpu.TiledResource)
{
//Aux-TT is sparsely updated, for TRs, upon change in mapping state ie
// null->non-null must be mapped
// non-null->null invalidated on AuxTT
uint8_t CpuUpdate = UpdateReq->DoNotWait || !(UpdateReq->UmdContext && UpdateReq->UmdContext->pCommandQueueHandle);
GMM_GFX_ADDRESS AuxVA = UpdateReq->AuxSurfVA;
if(UpdateReq->BaseResInfo->GetResFlags().Gpu.UnifiedAuxSurface)
{
GMM_UNIFIED_AUX_TYPE AuxType = GMM_AUX_CCS;
AuxType = (UpdateReq->BaseResInfo->GetResFlags().Gpu.Depth && UpdateReq->BaseResInfo->GetResFlags().Gpu.CCS) ? GMM_AUX_ZCS : AuxType;
AuxVA = UpdateReq->BaseGpuVA + GmmResGetAuxSurfaceOffset(UpdateReq->BaseResInfo, AuxType);
}
}
else
{
GMM_GFX_ADDRESS AuxVA = {0};
GMM_GFX_ADDRESS UVAuxVA = {0};
GMM_GFX_SIZE_T YPlaneSize = 0;
uint32_t MaxPlanes = 1;
if(!UpdateReq->AuxResInfo && UpdateReq->BaseResInfo->GetResFlags().Gpu.UnifiedAuxSurface)
{
GMM_UNIFIED_AUX_TYPE AuxType = GMM_AUX_CCS;
AuxType = (UpdateReq->BaseResInfo->GetResFlags().Gpu.Depth &&
UpdateReq->BaseResInfo->GetResFlags().Gpu.CCS) ?
GMM_AUX_ZCS :
AuxType;
AuxVA = UpdateReq->BaseGpuVA + GmmResGetAuxSurfaceOffset(UpdateReq->BaseResInfo, AuxType);
//For UV Packed, Gen12 e2e compr supported formats have 2 planes per surface
//Each has distinct Aux surface, Y-plane/UV-plane must be mapped to respective Y/UV Aux surface
if(GmmIsPlanar(UpdateReq->BaseResInfo->GetResourceFormat()))
{
GMM_REQ_OFFSET_INFO ReqInfo = {0};
ReqInfo.Plane = GMM_PLANE_U;
ReqInfo.ReqRender = 1;
MaxPlanes = 2;
UpdateReq->BaseResInfo->GetOffset(ReqInfo);
YPlaneSize = ReqInfo.Render.Offset64;
UVAuxVA = UpdateReq->BaseGpuVA + GmmResGetAuxSurfaceOffset(UpdateReq->BaseResInfo, GMM_AUX_UV_CCS);
}
}
//Per-plane Aux-TT map called with per-plane base/Aux address/size
for(uint32_t i = 0; i < MaxPlanes; i++)
{
GMM_GFX_SIZE_T SurfSize = (MaxPlanes > 1 && UpdateReq->BaseResInfo->GetArraySize() > 1) ?
(UpdateReq->BaseResInfo->GetQPitchPlanar(GMM_NO_PLANE) * UpdateReq->BaseResInfo->GetRenderPitch()) :
UpdateReq->BaseResInfo->GetSizeMainSurface();
GMM_GFX_SIZE_T MapSize = (i == 0) ? ((MaxPlanes > 1) ? YPlaneSize : SurfSize) : SurfSize - YPlaneSize;
GMM_GFX_ADDRESS BaseSurfVA = (UpdateReq->AuxResInfo || i == 0) ? UpdateReq->BaseGpuVA :
UpdateReq->BaseGpuVA + YPlaneSize;
GMM_GFX_ADDRESS AuxSurfVA = (UpdateReq->AuxResInfo) ? UpdateReq->AuxSurfVA : (i > 0 ? UVAuxVA : AuxVA);
//Luma plane reset LumaChroma bit
((GMM_AUXTTL1e *)&PartialL1e)->LumaChroma = (i == 0) ? 0 : 1;
uint32_t ArrayEle = GFX_MAX(((MaxPlanes > 1) ?
UpdateReq->BaseResInfo->GetArraySize() :
1),
1);
for(uint32_t j = 0; j < ArrayEle; j++)
{
BaseSurfVA += ((j > 0) ? (UpdateReq->BaseResInfo->GetQPitchPlanar(GMM_PLANE_Y) * UpdateReq->BaseResInfo->GetRenderPitch()) : 0);
AuxSurfVA += (UpdateReq->AuxResInfo ?
((j > 0) ? (UpdateReq->AuxResInfo->GetQPitchPlanar(GMM_PLANE_Y) * UpdateReq->BaseResInfo->GetRenderPitch()) : 0) :
((j > 0) ? UpdateReq->BaseResInfo->GetAuxQPitch() : 0));
//(Flat mapping): Remove main/aux resInfo from params
Status = AuxTTObj->MapValidEntry(UpdateReq->UmdContext, BaseSurfVA, MapSize, UpdateReq->BaseResInfo,
AuxSurfVA, UpdateReq->AuxResInfo, PartialL1e, 1);
if(Status != GMM_SUCCESS)
{
GMM_ASSERTDPF(0, "Insufficient memory, free resources and try again");
EXIT_CRITICAL_SECTION
return Status;
}
}
}
}
}
else
{
//Invalidate all mappings for given main surface
AuxTTObj->InvalidateTable(UpdateReq->UmdContext, UpdateReq->BaseGpuVA, UpdateReq->BaseResInfo->GetSizeMainSurface(), UpdateReq->DoNotWait);
}
EXIT_CRITICAL_SECTION
return GMM_SUCCESS;
}
#if defined(__linux__) && !_WIN32
/////////////////////////////////////////////////////////////////////////////////////
/// Gets size of PageTable buffer object (BOs) list
///
/// @param[in] TTFlags: Flags specifying PageTable-type for which BO-count required
/// @return non-zero if BO list is created. Zero otherwise.
/////////////////////////////////////////////////////////////////////////////////////
int GmmLib::GmmPageTableMgr::GetNumOfPageTableBOs(uint8_t TTFlags)
{
int NumBO = 0;
__GMM_ASSERTPTR(TTFlags & AUXTT, 0);
ENTER_CRITICAL_SECTION
if(AuxTTObj && AuxTTObj->GetL3Handle())
NumBO++;
NumBO += NumNodePoolElements;
EXIT_CRITICAL_SECTION
return NumBO;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Gets size of PageTable buffer object (BOs) list
///
/// @param[in] TTFlags: Flags specifying PageTable-type for which BO-count required
/// @param[in][out] BOList: pointer to memory where PageTable BO*(s) must be sent
/// @return non-zero if BO list is created. Zero otherwise.
/////////////////////////////////////////////////////////////////////////////////////
int GmmLib::GmmPageTableMgr::GetPageTableBOList(uint8_t TTFlags, void *BOList)
{
int NumBO = GetNumOfPageTableBOs(TTFlags);
HANDLE * Handles = (HANDLE *)BOList;
GmmLib::GMM_PAGETABLEPool *Pool;
__GMM_ASSERTPTR(TTFlags & AUXTT, 0);
__GMM_ASSERTPTR(BOList, 0);
__GMM_ASSERTPTR(NumBO, 0);
ENTER_CRITICAL_SECTION
if(AuxTTObj && AuxTTObj->GetL3Handle())
Handles[0] = AuxTTObj->GetL3Handle();
Pool = pPool;
for(int i = 0; i < NumNodePoolElements; i++)
{
if(Pool)
{
Handles[i + 1] = Pool->GetPoolHandle();
Pool = Pool->GetNextPool();
}
}
EXIT_CRITICAL_SECTION
return NumBO;
}
#endif
/////////////////////////////////////////////////////////////////////////////////////
/// Releases GmmPageTableMgr, deleting root-tables and existing page-table pools
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::GmmPageTableMgr::~GmmPageTableMgr()
{
GMM_CLIENT ClientType;
GET_GMM_CLIENT_TYPE(pClientContext, ClientType);
if(pPool)
{
ENTER_CRITICAL_SECTION
pPool->__DestroyPageTablePool(&DeviceCbInt, hCsr);
NumNodePoolElements = 0;
EXIT_CRITICAL_SECTION
}
if(AuxTTObj)
{
DeleteCriticalSection(&PoolLock);
if(AuxTTObj)
{
if(AuxTTObj->NullL1Table)
{
delete AuxTTObj->NullL1Table;
}
if(AuxTTObj->NullL2Table)
{
delete AuxTTObj->NullL2Table;
}
AuxTTObj->DestroyL3Table();
delete AuxTTObj;
AuxTTObj = NULL;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Instantiates and zeroes out GmmPageTableMgr
///
/// @return GmmPageTableMgr*
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::GmmPageTableMgr::GmmPageTableMgr()
{
this->AuxTTObj = NULL;
this->pPool = NULL;
this->NumNodePoolElements = 0;
this->pClientContext = NULL;
this->hCsr = NULL;
memset(&DeviceCb, 0, sizeof(GMM_DEVICE_CALLBACKS));
memset(&DeviceCbInt, 0, sizeof(GMM_DEVICE_CALLBACKS_INT));
}

View File

@ -0,0 +1,670 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Description: Contains functions of internal classes
(ie PageTablePool, PageTable, Table), that support
user mode page table management
============================================================================*/
#include "Internal/Common/GmmLibInc.h"
#include "../TranslationTable/GmmUmdTranslationTable.h"
#include "Internal/Common/Texture/GmmTextureCalc.h"
#if !defined(__GMM_KMD)
#if defined(__linux__)
#include "Internal/Linux/GmmResourceInfoLinInt.h"
#define _aligned_free(ptr) free(ptr)
#endif
//=============================================================================
//
// Function: AllocateL3Table
//
// Desc: Allocates (always resident SVM) memory for AUXTT\L3 Table, and updates AUXTT object
//
// Parameters:
// pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
//
// Returns:
// GMM_SUCCESS on success,
// GMM_INVALIDPARAM on invalid parameter(s)
// GMM_OUT_OF_MEMORY on memory allocation failure, failure to make resident
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::PageTable::AllocateL3Table(uint32_t L3TableSize, uint32_t L3AddrAlignment)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_DEVICE_ALLOC Alloc = {0};
__GMM_ASSERTPTR(PageTableMgr, GMM_INVALIDPARAM);
EnterCriticalSection(&TTLock);
Alloc.Size = L3TableSize;
Alloc.Alignment = L3AddrAlignment;
Alloc.hCsr = PageTableMgr->hCsr;
Status = __GmmDeviceAlloc(pClientContext, &PageTableMgr->DeviceCbInt, &Alloc);
if(Status != GMM_SUCCESS)
{
LeaveCriticalSection(&TTLock);
return Status;
}
TTL3.GfxAddress = GMM_GFX_ADDRESS_CANONIZE(Alloc.GfxVA);
TTL3.CPUAddress = Alloc.CPUVA;
TTL3.NeedRegisterUpdate = true;
TTL3.L3Handle = (HANDLE)(uintptr_t)Alloc.Handle;
TTL3.pGmmResInfo = (GMM_RESOURCE_INFO *)Alloc.Priv;
// Invalidate L3e's
for(int i = 0; i < (GMM_L3_SIZE(TTType)); i++)
{
//initialize L3e ie mark all entries with Null tile/invalid value
((GMM_AUXTTL3e *)TTL3.CPUAddress)[i].Value = 0;
}
LeaveCriticalSection(&TTLock);
return Status;
}
//=============================================================================
//
// Function: __IsUnusedTRTTPoolOverLimit
//
// Desc: Checks if unused TRTTPools have reached residency limit and must be freed.
//
// Parameters:
// pTRTT_Obj: per-device TT object. Contains TT node info
// OverLimitSize: Size in bytes that can be freed
//
// Returns:
// True, if unused TTPool reached max. residency limit
// False, otherwise
//-----------------------------------------------------------------------------
bool GmmLib::GmmPageTablePool::__IsUnusedTRTTPoolOverLimit(GMM_GFX_SIZE_T *OverLimitSize)
{
GMM_GFX_SIZE_T UnusedTrTTPoolSize = 0;
GmmLib::GMM_PAGETABLEPool *Pool = NULL;
Pool = this;
while(Pool)
{
if(Pool->NumFreeNodes == PAGETABLE_POOL_MAX_NODES)
{
UnusedTrTTPoolSize += PAGETABLE_POOL_SIZE;
}
Pool = Pool->NextPool;
}
*OverLimitSize = (UnusedTrTTPoolSize > PAGETABLE_POOL_MAX_UNUSED_SIZE) ? (UnusedTrTTPoolSize - PAGETABLE_POOL_MAX_UNUSED_SIZE) : 0;
return (UnusedTrTTPoolSize > PAGETABLE_POOL_MAX_UNUSED_SIZE) ? true : false;
}
//=============================================================================
//
// Function: AllocateL1L2Table
//
// Desc: Assigns pages from AUXTTPool for L1/L2Table for translation of given TRVA
//
// Parameters:
// pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
// TileAddr: Tiled Resource Virtual address
//
// Returns:
// L2Table/L1Table Address
//-----------------------------------------------------------------------------
void GmmLib::PageTable::AllocateL1L2Table(GMM_GFX_ADDRESS TileAddr, GMM_GFX_ADDRESS *L1TableAdr, GMM_GFX_ADDRESS *L2TableAdr)
{
GMM_GFX_ADDRESS L3TableAdr = GMM_NO_TABLE;
uint32_t L3eIdx = static_cast<uint32_t>(GMM_L3_ENTRY_IDX(TTType, TileAddr));
uint32_t L2eIdx = static_cast<uint32_t>(GMM_L2_ENTRY_IDX(TTType, TileAddr));
GmmLib::LastLevelTable *pL1Tbl = NULL;
*L2TableAdr = GMM_NO_TABLE;
*L1TableAdr = GMM_NO_TABLE;
if(TTL3.L3Handle)
{
L3TableAdr = TTL3.GfxAddress;
}
else
{
//Should never hit -- L3Table is allocated during device creation
__GMM_ASSERT(false);
}
if(pTTL2[L3eIdx].GetPool())
{
GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
PoolElem = pTTL2[L3eIdx].GetPool();
*L2TableAdr = (PoolElem != NULL) ? PoolElem->GetGfxAddress() + (PAGE_SIZE * pTTL2[L3eIdx].GetNodeIdx()) : GMM_NO_TABLE;
}
else
{
uint32_t PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
POOL_TYPE PoolType = POOL_TYPE_AUXTTL2;
PoolElem = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType);
if(PoolElem)
{
pTTL2[L3eIdx] = MidLevelTable(PoolElem, PoolNodeIdx, PoolElem->GetNodeBBInfoAtIndex(PoolNodeIdx));
*L2TableAdr = PoolElem->GetGfxAddress() + PAGE_SIZE * PoolNodeIdx; //PoolNodeIdx must be multiple of 8 (Aux L2) and multiple of 2 (Aux L1)
ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, NodesPerTable)
}
}
pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx);
if(pL1Tbl)
{
GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
PoolElem = pL1Tbl->GetPool();
*L1TableAdr = (PoolElem != NULL) ? PoolElem->GetGfxAddress() + (PAGE_SIZE * pL1Tbl->GetNodeIdx()) : GMM_NO_TABLE;
}
else
{
//Allocate L1 Table
uint32_t PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
POOL_TYPE PoolType = POOL_TYPE_AUXTTL1;
PoolElem = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType); //Recognize if Aux-L1 being allocated
if(PoolElem)
{
pL1Tbl = new GmmLib::LastLevelTable(PoolElem, PoolNodeIdx, GMM_L1_SIZE_DWORD(TTType, GetGmmLibContext()), L2eIdx); // use TR vs Aux L1_Size_DWORD
if(pL1Tbl)
{
*L1TableAdr = PoolElem->GetGfxAddress() + PAGE_SIZE * PoolNodeIdx; //PoolNodeIdx should reflect 1 node per Tr-table and 2 nodes per AUX L1 TABLE
if(PoolNodeIdx != PAGETABLE_POOL_MAX_NODES)
{
uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES : 1;
ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, PerTableNodes)
}
pTTL2[L3eIdx].InsertInList(pL1Tbl);
}
}
}
}
//=============================================================================
//
// Function: AllocateDummyTables
//
// Desc: Assigns pages from AUXTTPool for Dummy L1/L2Table
//
// Parameters:
// L2Table - Ptr to initiatize dummy L2Table
// L1Table - Ptr to initiatize dummy L1Table
//
// Returns:
// L2Table/L1Tables
//-----------------------------------------------------------------------------
void GmmLib::PageTable::AllocateDummyTables(GmmLib::Table **L2Table, GmmLib::Table **L1Table)
{
GMM_GFX_ADDRESS L3TableAdr = GMM_NO_TABLE;
GmmLib::LastLevelTable *pL1Tbl = NULL;
if(TTL3.L3Handle)
{
L3TableAdr = TTL3.GfxAddress;
}
else
{
//Should never hit -- L3Table is allocated during device creation
__GMM_ASSERT(false);
}
//Allocate dummy L2Table
{
uint32_t PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
POOL_TYPE PoolType = POOL_TYPE_AUXTTL2;
PoolElem = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType);
if(PoolElem)
{
*L2Table = new GmmLib::MidLevelTable(PoolElem, PoolNodeIdx, PoolElem->GetNodeBBInfoAtIndex(PoolNodeIdx));
ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, NodesPerTable)
}
}
//Allocate dummy L1Table
{
uint32_t PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
POOL_TYPE PoolType = POOL_TYPE_AUXTTL1;
PoolElem = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType); //Recognize if Aux-L1 being allocated
if(PoolElem)
{
*L1Table = new GmmLib::LastLevelTable(PoolElem, PoolNodeIdx, GMM_L1_SIZE_DWORD(TTType, GetGmmLibContext()), 0); // use TR vs Aux L1_Size_DWORD
if(*L1Table)
{
if(PoolNodeIdx != PAGETABLE_POOL_MAX_NODES)
{
uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES : 1;
ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, PerTableNodes)
}
}
}
}
}
//=============================================================================
//
// Function: GetL1L2TableAddr
//
// Desc: For given tile address, returns L1/L2 Table address if the table exists
//
// Parameters:
// pAUXTT_Obj: per-device AUX-TT object. Contains AXUTT node info
// TileAddr: Tiled Resource Virtual address
//
// Returns:
// L2Table/L1Table Address
//-----------------------------------------------------------------------------
void GmmLib::PageTable::GetL1L2TableAddr(GMM_GFX_ADDRESS TileAddr, GMM_GFX_ADDRESS *L1TableAdr, GMM_GFX_ADDRESS *L2TableAdr)
{
GMM_GFX_SIZE_T L3eIdx, L2eIdx, L1eIdx;
GMM_GFX_ADDRESS L3TableAdr = GMM_NO_TABLE;
*L2TableAdr = GMM_NO_TABLE;
*L1TableAdr = GMM_NO_TABLE;
L3eIdx = GMM_L3_ENTRY_IDX(TTType, TileAddr);
L2eIdx = GMM_L2_ENTRY_IDX(TTType, TileAddr);
L1eIdx = GMM_L1_ENTRY_IDX(TTType, TileAddr, GetGmmLibContext());
__GMM_ASSERT(TTL3.L3Handle);
L3TableAdr = TTL3.GfxAddress;
if(pTTL2[L3eIdx].GetPool())
{
GmmLib::GMM_PAGETABLEPool *Pool = NULL;
GmmLib::LastLevelTable * pL1Tbl = NULL;
Pool = pTTL2[L3eIdx].GetPool();
if(Pool)
{
__GMM_ASSERT(Pool->GetNumFreeNode() != PAGETABLE_POOL_MAX_NODES);
__GMM_ASSERT(pTTL2[L3eIdx].GetNodeIdx() < PAGETABLE_POOL_MAX_NODES);
__GMM_ASSERT(Pool->GetNodeUsageAtIndex(pTTL2[L3eIdx].GetNodeIdx() / (32 * NodesPerTable)) != 0);
*L2TableAdr = Pool->GetGfxAddress() + PAGE_SIZE * (pTTL2[L3eIdx].GetNodeIdx());
}
pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx);
if(pL1Tbl && pL1Tbl->GetPool())
{
Pool = NULL;
Pool = pL1Tbl->GetPool();
if(Pool)
{
uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES : 1;
__GMM_ASSERT(Pool->GetNumFreeNode() != PAGETABLE_POOL_MAX_NODES);
__GMM_ASSERT(pL1Tbl->GetNodeIdx() < PAGETABLE_POOL_MAX_NODES);
__GMM_ASSERT(Pool->GetNodeUsageAtIndex(pL1Tbl->GetNodeIdx() / (32 * PerTableNodes)) != 0);
*L1TableAdr = Pool->GetGfxAddress() + PAGE_SIZE * (pL1Tbl->GetNodeIdx());
}
}
}
}
//=============================================================================
//
// Function: GetMappingType
//
// Desc: For given gfx address and size, returns MappingType (null/non-null or
// Valid/Invalid) of GfxVA and first gfx address have reverse mapping
//
/// @param[in] GfxVA: Gfx Address whose mapping type is being queried
/// @param[in] Size: Size of interested Gfx address range
/// @param[out] LastAddr : 1st Gfx Address having reverse mapping type
//
/// @return 1/0 : for non-null/valid vs null/invalid mapping
//-----------------------------------------------------------------------------
uint8_t GmmLib::PageTable::GetMappingType(GMM_GFX_ADDRESS GfxVA, GMM_GFX_SIZE_T Size, GMM_GFX_ADDRESS &LastAddr)
{
GMM_GFX_SIZE_T L3eIdx, L2eIdx, L1eIdx, L1EntrySize;
uint8_t MapType = 0; //true for non-null, false for null mapped
bool bFoundLastVA = false, bTerminate = false;
GMM_GFX_ADDRESS TileAddr = GfxVA;
L3eIdx = GMM_L3_ENTRY_IDX(TTType, GfxVA);
L2eIdx = GMM_L2_ENTRY_IDX(TTType, GfxVA);
L1eIdx = GMM_L1_ENTRY_IDX(TTType, GfxVA, GetGmmLibContext());
L1EntrySize = (!WA16K(GetGmmLibContext())) ? GMM_KBYTE(64) : GMM_KBYTE(16);
EnterCriticalSection(&TTLock);
__GMM_ASSERT(TTL3.L3Handle);
#define GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx) \
{ \
L1eIdx = 0; \
L2eIdx++; \
if(L2eIdx == (GMM_L2_SIZE(TTType))) \
{ \
L2eIdx = 0; \
L3eIdx++; \
if(L3eIdx == (GMM_L3_SIZE(TTType))) \
{ \
bTerminate = true; \
} \
} \
}
#define GET_NEXT_L2TABLE(L1eIdx, L2eIdx, L3eIdx) \
{ \
L1eIdx = L2eIdx = 0; \
L3eIdx++; \
if(L3eIdx == (GMM_L3_SIZE(TTType))) \
{ \
bTerminate = true; \
} \
}
while(!(bFoundLastVA || bTerminate) && (TileAddr < GfxVA + Size))
{
if(pTTL2[L3eIdx].GetPool())
{
GmmLib::LastLevelTable *pL1Tbl = NULL;
pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx);
if(pL1Tbl && pL1Tbl->GetPool())
{
uint32_t LastBit = 0;
uint32_t i = static_cast<uint32_t>(L1eIdx) / 32;
while(!bFoundLastVA && i < (uint32_t)(GMM_L1_SIZE_DWORD(TTType, GetGmmLibContext())))
{
uint32_t UsageDW = pL1Tbl->GetUsedEntries()[i++];
uint32_t BitNum = 31;
if(GfxVA == TileAddr)
{
BitNum = L1eIdx % 32;
MapType = ((UsageDW & __BIT(BitNum)) ? 0x1 : 0x0); //true for non-null, false for null mapped
UsageDW = (!MapType) ? UsageDW : ~UsageDW;
UsageDW = ((uint64_t)UsageDW >> (BitNum + 1)) << (BitNum + 1); // clear lsb <= BitNum
}
else
{
UsageDW = (!MapType) ? UsageDW : ~UsageDW;
}
if(_BitScanForward((uint32_t *)&LastBit, UsageDW)) // Gets lsb > BitNum, having reverse mapType
{
bFoundLastVA = true;
uint32_t NumTiles = (GfxVA == TileAddr) ? (LastBit - BitNum) : LastBit;
LastAddr = TileAddr + NumTiles * L1EntrySize;
}
else
{
uint32_t NumTiles = (GfxVA == TileAddr) ? (32 - BitNum) : 32;
TileAddr += NumTiles * L1EntrySize;
}
}
if(!bFoundLastVA)
{
GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx);
}
}
else //L2Entry is NULL
{
if(MapType) //First hit null-map
{
LastAddr = TileAddr;
bFoundLastVA = true;
}
else
{
GMM_GFX_SIZE_T NumTiles = GMM_L1_SIZE(TTType, GetGmmLibContext());
if(GfxVA == TileAddr)
{
MapType = false;
NumTiles -= L1eIdx;
}
TileAddr += NumTiles * L1EntrySize;
GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx)
}
}
}
else //L3entry is NULL
{
if(MapType) //First hit null-map
{
LastAddr = TileAddr;
bFoundLastVA = true;
}
else
{
GMM_GFX_SIZE_T NumTiles = 0;
if(GfxVA == TileAddr)
{
MapType = false;
NumTiles = (GMM_L2_SIZE(TTType) - L2eIdx) * (GMM_L1_SIZE(TTType, GetGmmLibContext()) - L1eIdx);
}
else
{
NumTiles = ((GMM_L2_SIZE(TTType)) * (GMM_L1_SIZE(TTType, GetGmmLibContext())));
}
TileAddr += NumTiles * L1EntrySize;
GET_NEXT_L2TABLE(L1eIdx, L2eIdx, L3eIdx)
}
}
}
if(!bFoundLastVA)
{
LastAddr = TileAddr;
}
LeaveCriticalSection(&TTLock);
return MapType;
}
//=============================================================================
//
// Function: TrackTableUsage
//
// Desc: For given tile address, updates Table Usage.If Table has all Nullmappings
// then its pool node can be unassigned
//
// Parameters:
// Type: Translation Table type (Aux)
// IsL1: Is called for L1table or L2 Table
// TileAddr: Tiled Resource Virtual address
// NullMapped: true if given tiled adr was null mapped, otherwise false
//
// Returns:
// true, if Table for given tile adr is all null mapped
// false,if Table does not exist or has non-null mapping
//-----------------------------------------------------------------------------
bool GmmLib::Table::TrackTableUsage(TT_TYPE Type, bool IsL1, GMM_GFX_ADDRESS TileAdr, bool NullMapped, GMM_LIB_CONTEXT *pGmmLibContext )
{
uint32_t EntryIdx;
uint32_t ElemNum = 0, BitNum = 0;
EntryIdx = IsL1 ? static_cast<uint32_t>(GMM_L1_ENTRY_IDX(Type, TileAdr, pGmmLibContext)) : static_cast<uint32_t>(GMM_L2_ENTRY_IDX(Type, TileAdr));
ElemNum = EntryIdx / (sizeof(UsedEntries[0]) * 8);
BitNum = EntryIdx % (sizeof(UsedEntries[0]) * 8);
if(NullMapped)
{
UsedEntries[ElemNum] &= ~(1 << BitNum);
}
else
{
UsedEntries[ElemNum] |= (1 << BitNum);
}
if(NullMapped)
{
int TableDWSize = IsL1 ? static_cast<int>(GMM_L1_SIZE_DWORD(Type, pGmmLibContext)) : static_cast<int>(GMM_L2_SIZE_DWORD(Type));
for(int i = 0; i < TableDWSize; i++)
{
if(UsedEntries[i])
{
return false;
}
}
}
return NullMapped ? true : false;
}
//=============================================================================
//
// Function: __IsTableNullMapped
//
// Desc: For given tile address, checks if given Table has all Nullmappings
// then its pool node can be unassigned
//
// Parameters:
// Type: Translation Table type (TR or Aux)
// IsL1: Is called for L1table or L2 Table
// TileAddr: Tiled Resource Virtual address
//
// Returns:
// true, if Table for given tile adr is all null mapped
// false,if Table has non-null mapping
//-----------------------------------------------------------------------------
bool GmmLib::Table::IsTableNullMapped(TT_TYPE Type, bool IsL1, GMM_GFX_ADDRESS TileAdr, GMM_LIB_CONTEXT *pGmmLibContext)
{
GMM_UNREFERENCED_PARAMETER(TileAdr);
int TableDWSize = IsL1 ? static_cast<int>(GMM_L1_SIZE_DWORD(Type, pGmmLibContext)) : static_cast<int>(GMM_L2_SIZE_DWORD(Type));
for(int i = 0; i < TableDWSize; i++)
{
if(UsedEntries[i])
{
return false;
}
}
return true;
}
//=============================================================================
//
// Function: __UpdatePoolFence
//
// Desc: Updates AUXTTPool's or Table's BBFenceObj/value with current BB fence
//
// Parameters:
// pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
// Table: L1/L2 table pointer
// L1Table: true for L1 Table, else false
// ClearNode: if true, Fence info is cleared for table
// false, Fence info is updated for table and pool
//-----------------------------------------------------------------------------
void GmmLib::Table::UpdatePoolFence(GMM_UMD_SYNCCONTEXT *UmdContext, bool ClearNode)
{
if(!ClearNode)
{
//update both node and pool with current fence/handle
PoolElem->GetPoolBBInfo().BBQueueHandle =
BBInfo.BBQueueHandle = UmdContext->BBFenceObj;
PoolElem->GetPoolBBInfo().BBFence =
BBInfo.BBFence = UmdContext->BBLastFence + 1; //Save incremented fence value, since DX does it during submission
}
else
{
//Clear node fence/handle
BBInfo.BBQueueHandle = 0;
BBInfo.BBFence = 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Releases all PageTable Pool(s) existing in Linked List
///
/// @param[in] DeviceCallbacks pointer to device callbacks structure
/// @return GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmPageTablePool::__DestroyPageTablePool(void *DeviceCallbacks, HANDLE hCsr)
{
GMM_STATUS Status = GMM_SUCCESS;
GMM_DEVICE_CALLBACKS_INT *DeviceCb = static_cast<GMM_DEVICE_CALLBACKS_INT *>(DeviceCallbacks);
GMM_PAGETABLEPool *Node = this, *Next = NULL;
GMM_CLIENT ClientType;
GMM_DEVICE_DEALLOC Dealloc = {0};
//Evict/Free gpu Va is implictly done by OS when de-allocating
while(Node)
{
Next = Node->NextPool;
GET_GMM_CLIENT_TYPE(Node->pClientContext, ClientType);
Dealloc.Handle = Node->PoolHandle;
Dealloc.GfxVA = Node->PoolGfxAddress;
Dealloc.Priv = Node->pGmmResInfo;
Dealloc.hCsr = hCsr;
Status = __GmmDeviceDealloc(ClientType, DeviceCb, &Dealloc, Node->pClientContext);
Node->PoolHandle = NULL;
Node->PoolGfxAddress = 0;
delete Node;
Node = Next;
}
return Status;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Releases memory allocated to PageTable's Root-table
///
/// @return GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::PageTable::DestroyL3Table()
{
GMM_STATUS Status = GMM_SUCCESS;
uint8_t hr = GMM_SUCCESS;
GMM_CLIENT ClientType;
GMM_DEVICE_DEALLOC Dealloc = {0};
GET_GMM_CLIENT_TYPE(pClientContext, ClientType);
EnterCriticalSection(&TTLock);
if(TTL3.L3Handle)
{
Dealloc.Handle = TTL3.L3Handle;
Dealloc.GfxVA = TTL3.GfxAddress;
Dealloc.Priv = TTL3.pGmmResInfo;
Dealloc.hCsr = PageTableMgr->hCsr;
Status = __GmmDeviceDealloc(ClientType, &PageTableMgr->DeviceCbInt, &Dealloc, pClientContext);
TTL3.L3Handle = NULL;
TTL3.GfxAddress = 0;
TTL3.CPUAddress = 0;
}
LeaveCriticalSection(&TTLock);
return Status;
}
#endif //!__GMM_KMD

View File

@ -0,0 +1,548 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Description: This file contains the class definitions for GmmPageTablePool
PageTable, and low-level Tables for user-mode PageTable management,
that is common for both Linux and Windows.
======================= end_copyright_notice ==================================*/
#pragma once
#include "External/Common/GmmPageTableMgr.h"
#ifdef __linux__
#include <pthread.h>
#include <string.h>
// Internal Linux version of MSDK APIs.
static inline void InitializeCriticalSection(pthread_mutex_t *mutex)
{
pthread_mutexattr_t Attr;
pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(mutex, &Attr);
}
static inline void DeleteCriticalSection(pthread_mutex_t *mutex)
{
pthread_mutex_destroy(mutex);
}
static inline void EnterCriticalSection(pthread_mutex_t *mutex)
{
pthread_mutex_lock(mutex);
}
static inline void LeaveCriticalSection(pthread_mutex_t *mutex)
{
pthread_mutex_unlock(mutex);
}
#ifndef _BitScanForwardDefined
static inline int _BitScanForward(uint32_t *index, uint32_t mask)
{
int i;
#ifdef __ANDROID__
i = ffs(mask);
#else
i = ffsl(mask);
#endif
if(i > 0)
{
*index = (uint32_t)(i - 1);
return i;
}
return 0;
}
#endif
#endif
#define GMM_L1_SIZE(TTType, pGmmLibContext) GMM_AUX_L1_SIZE(pGmmLibContext)
#define GMM_L1_SIZE_DWORD(TTType, pGmmLibContext) GMM_AUX_L1_SIZE_DWORD(pGmmLibContext)
#define GMM_L2_SIZE(TTType) GMM_AUX_L2_SIZE
#define GMM_L2_SIZE_DWORD(TTType) GMM_AUX_L2_SIZE_DWORD
#define GMM_L3_SIZE(TTType) GMM_AUX_L3_SIZE
#define GMM_L1_ENTRY_IDX(TTType, GfxAddress, pGmmLibContext) GMM_AUX_L1_ENTRY_IDX((GfxAddress), (pGmmLibContext))
#define GMM_L2_ENTRY_IDX(TTType, GfxAddress) GMM_AUX_L2_ENTRY_IDX((GfxAddress))
#define GMM_L3_ENTRY_IDX(TTType, GfxAddress) GMM_AUX_L3_ENTRY_IDX((GfxAddress))
#ifdef GMM_ULT
#define GMM_L1_ENTRY_IDX_EXPORTED(TTType, GfxAddress, WA64KEx) GMM_AUX_L1_ENTRY_IDX_EXPORTED((GfxAddress), WA64KEx)
#endif
#ifdef __cplusplus
#include "External/Common/GmmMemAllocator.hpp"
//HW provides single-set of TR/Aux-TT registers for non-privileged programming
//Engine-specific offsets are HW-updated with programmed values.
#define GET_L3ADROFFSET(TRTT, L3AdrOffset, pGmmLibContext) \
L3AdrOffset = 0x4200;
#define ASSIGN_POOLNODE(Pool, NodeIdx, PerTableNodes) { \
(Pool)->GetNodeUsageAtIndex((NodeIdx) / (32 *(PerTableNodes))) |= __BIT(((NodeIdx) / (PerTableNodes)) % 32); \
(Pool)->GetNodeBBInfoAtIndex(NodeIdx) = SyncInfo(); \
(Pool)->GetNumFreeNode() -= (PerTableNodes); \
}
#define DEASSIGN_POOLNODE(PageTableMgr, UmdContext, Pool, NodeIdx, PerTableNodes) { \
(Pool)->GetNodeUsageAtIndex((NodeIdx) / (32 * (PerTableNodes))) &= ~__BIT(((NodeIdx) / (PerTableNodes)) % 32 ); \
(Pool)->GetNumFreeNode() += (PerTableNodes); \
if((Pool)->GetNumFreeNode() == PAGETABLE_POOL_MAX_NODES) { \
PageTableMgr->__ReleaseUnusedPool((UmdContext)); \
} \
}
namespace GmmLib
{
#define PAGETABLE_POOL_MAX_NODES 512 //Max. number of L2/L1 tables pool contains
#define PAGETABLE_POOL_SIZE_IN_DWORD PAGETABLE_POOL_MAX_NODES / 32
#define PAGETABLE_POOL_SIZE PAGETABLE_POOL_MAX_NODES * PAGE_SIZE //Pool for L2/L1 table allocation
#define AUX_L2TABLE_SIZE_IN_POOLNODES 8 //Aux L2 is 32KB
#define AUX_L1TABLE_SIZE_IN_POOLNODES 2 //Aux L1 is 8KB
#define PAGETABLE_POOL_MAX_UNUSED_SIZE GMM_MBYTE(16) //Max. size of unused pool, driver keeps resident
//////////////////////////////////////////////////////////////////////////////////////////////
/// Contains functions and members for GmmPageTablePool.
/// PageTablePool is a Linked-list, provides common location for both Aux TT and TR-TT pages
/// Separate NodePool (linked-list element) kept for each PoolType, for cleaner management in
/// per-table size
/////////////////////////////////////////////////////////////////////////////////////////////
class GmmPageTablePool
{
private:
//PageTablePool allocation descriptor
GMM_RESOURCE_INFO* pGmmResInfo;
HANDLE PoolHandle;
GMM_GFX_ADDRESS PoolGfxAddress;
GMM_GFX_ADDRESS CPUAddress; //LMEM-cpuvisible adr
POOL_TYPE PoolType; //Separate Node-pools for TR-L2, TR-L1, Aux-L2, Aux-L1 usages-
//PageTablePool usage descriptors
int NumFreeNodes; //has value {0 to Pool_Max_nodes}
uint32_t* NodeUsage; //destined node state (updated during node assignment and removed based on destined state of L1/L2 Table
//that used the pool node)
//Aux-Pool node-usage tracked at every eighth/second node(for L2 vs L1)
//ie 1b per node for TR-table, 1b per 8-nodes for Aux-L2table, 1b per 2-nodes for AuxL1-table
//array size= POOL_SIZE_IN_DWORD for TR, =POOL_SIZE_IN_DWORD/8 for AuxL2, POOL_SIZE_IN_DWORD/2 for AuxL1
SyncInfo* NodeBBInfo; //BB info for pending Gpu usage of each pool node
//array of size MaxPoolNodes for TR, =MaxPoolNodes / 8 for Aux, MaxPoolNodes / 2 for AuxL1
SyncInfo PoolBBInfo; //BB info for Gpu usage of the Pool (most recent of pool node BB info)
GmmPageTablePool* NextPool; //Next node-Pool in the LinkedList
GmmClientContext *pClientContext; ///< ClientContext of the client creating this Object
public:
GmmPageTablePool() :
pGmmResInfo(NULL),
PoolHandle(),
PoolGfxAddress(0x0),
CPUAddress(0x0),
PoolType(POOL_TYPE_TRTTL1),
NumFreeNodes(PAGETABLE_POOL_MAX_NODES),
NodeUsage(NULL),
NodeBBInfo(NULL),
PoolBBInfo(),
NextPool(NULL),
pClientContext(NULL)
{
}
GmmPageTablePool(HANDLE hAlloc, GMM_RESOURCE_INFO* pGmmRes, GMM_GFX_ADDRESS SysMem, POOL_TYPE Type) :
GmmPageTablePool()
{
PoolHandle = hAlloc;
pGmmResInfo = pGmmRes;
PoolGfxAddress = SysMem;
CPUAddress = PoolGfxAddress;
NextPool = NULL;
NumFreeNodes = PAGETABLE_POOL_MAX_NODES;
PoolType = Type;
int DwordPoolSize = (Type == POOL_TYPE_AUXTTL1) ? PAGETABLE_POOL_SIZE_IN_DWORD / AUX_L1TABLE_SIZE_IN_POOLNODES
: (Type == POOL_TYPE_AUXTTL2) ? PAGETABLE_POOL_SIZE_IN_DWORD / AUX_L2TABLE_SIZE_IN_POOLNODES
: PAGETABLE_POOL_SIZE_IN_DWORD;
NodeUsage = new uint32_t[DwordPoolSize]();
NodeBBInfo = new SyncInfo[DwordPoolSize * 32]();
if (pGmmResInfo)
{
pClientContext = pGmmResInfo->GetGmmClientContext();
}
}
GmmPageTablePool(HANDLE hAlloc, GMM_RESOURCE_INFO* pGmmRes, GMM_GFX_ADDRESS GfxAdr, GMM_GFX_ADDRESS CPUAdr, POOL_TYPE Type) :
GmmPageTablePool(hAlloc, pGmmRes, GfxAdr, Type)
{
CPUAddress = (CPUAdr != GfxAdr) ? CPUAdr : GfxAdr;
}
~GmmPageTablePool()
{
delete[] NodeUsage;
delete[] NodeBBInfo;
}
GmmPageTablePool* InsertInList(GmmPageTablePool* NewNode)
{
GmmPageTablePool *Node = this;
while (Node->NextPool)
{
Node = Node->NextPool;
}
Node->NextPool = NewNode;
return Node->NextPool;
}
GmmPageTablePool* InsertInListAtBegin(GmmPageTablePool* NewNode)
{
GmmPageTablePool *Node = this;
NewNode->NextPool = Node;
return NewNode;
}
GmmPageTablePool* &GetNextPool() { return NextPool; }
HANDLE& GetPoolHandle() { return PoolHandle; }
POOL_TYPE& GetPoolType() { return PoolType; }
int& GetNumFreeNode() { return NumFreeNodes; }
SyncInfo& GetPoolBBInfo() { return PoolBBInfo; }
uint32_t& GetNodeUsageAtIndex(int j) { return NodeUsage[j]; }
SyncInfo& GetNodeBBInfoAtIndex(int j)
{
int BBInfoNodeIdx = (PoolType == POOL_TYPE_AUXTTL1) ? j / AUX_L1TABLE_SIZE_IN_POOLNODES
: (PoolType == POOL_TYPE_AUXTTL2) ? j / AUX_L2TABLE_SIZE_IN_POOLNODES
: j;
return NodeBBInfo[BBInfoNodeIdx];
}
GMM_GFX_ADDRESS GetGfxAddress() { return PoolGfxAddress; }
GMM_GFX_ADDRESS GetCPUAddress() { return CPUAddress; }
GMM_RESOURCE_INFO* &GetGmmResInfo() { return pGmmResInfo; }
bool IsPoolInUse(SyncInfo BBInfo) {
if (NumFreeNodes < PAGETABLE_POOL_MAX_NODES ||
(PoolBBInfo.BBQueueHandle == BBInfo.BBQueueHandle &&
PoolBBInfo.BBFence == BBInfo.BBFence + 1)) //Pool will be used by next BB submission, freeing it will cause page fault
{
return true;
}
return false;
}
bool __IsUnusedTRTTPoolOverLimit(GMM_GFX_SIZE_T * OverLimitSize);
void ClearBBReference(void * BBQHandle);
GMM_STATUS __DestroyPageTablePool(void * DeviceCallbacks,HANDLE hCsr);
};
//////////////////////////////////////////////////////////////////////////////////////////////
/// Contains functions and members for Table.
/// Table defines basic building block for tables at different page-table levels
/////////////////////////////////////////////////////////////////////////////////////////////
class Table
{
protected:
GMM_PAGETABLEPool *PoolElem; //L2 Pool ptr different for L2Tables when Pool_nodes <512
int PoolNodeIdx; //pool node idx used for L2 Table
SyncInfo BBInfo; //BB Handle/fence using Table
uint32_t* UsedEntries; //Tracks which L1/L2 entries are being used
//array size GMM_L1_SIZE_DWORD(TT-type) for LastLevelTable, MidLeveltable(??)
//array of 1024/32=32 DWs for TR-table, 4096/32 =512 for Aux-Table
public:
Table() :
PoolElem(NULL),
PoolNodeIdx(),
BBInfo(),
UsedEntries(NULL)
{
}
int& GetNodeIdx() { return PoolNodeIdx; }
GmmPageTablePool* &GetPool() { return PoolElem; }
GMM_GFX_ADDRESS GetCPUAddress() { return (PoolElem->GetCPUAddress() + (PoolNodeIdx * PAGE_SIZE)); }
SyncInfo& GetBBInfo() { return BBInfo; }
uint32_t* &GetUsedEntries() { return UsedEntries; }
bool TrackTableUsage(TT_TYPE Type, bool IsL1, GMM_GFX_ADDRESS TileAdr, bool NullMapped,GMM_LIB_CONTEXT* pGmmLibContext);
bool IsTableNullMapped(TT_TYPE Type, bool IsL1, GMM_GFX_ADDRESS TileAdr,GMM_LIB_CONTEXT *pGmmLibContext);
void UpdatePoolFence(GMM_UMD_SYNCCONTEXT * UmdContext, bool ClearNode);
};
//////////////////////////////////////////////////////////////////////////////////////////////
/// Contains functions and members for LastLevelTable.
/// LastLevelTable defines leaf level tables in multi-level pageTable structure
/////////////////////////////////////////////////////////////////////////////////////////////
class LastLevelTable : public Table
{
private:
uint32_t L2eIdx;
LastLevelTable *pNext;
public:
LastLevelTable() : Table(),
L2eIdx() //Pass in Aux vs TR table's GMM_L2_SIZE and initialize L2eIdx?
{
pNext = NULL;
}
LastLevelTable(GMM_PAGETABLEPool* Elem, int NodeIdx, int DwordL1e, int L2eIndex)
: LastLevelTable()
{
PoolElem = Elem;
PoolNodeIdx = NodeIdx;
BBInfo = Elem->GetNodeBBInfoAtIndex(NodeIdx);
L2eIdx = L2eIndex;
pNext = NULL;
UsedEntries = new uint32_t[DwordL1e]();
}
~LastLevelTable()
{
delete[] UsedEntries;
}
int GetL2eIdx() {
return L2eIdx;
}
LastLevelTable* &Next() {
return pNext;
}
};
//////////////////////////////////////////////////////////////////////////////////////////////
/// Contains functions and members for MidLevelTable.
/// MidLevelTable defines secondary level tables in multi-level pageTable structure
/////////////////////////////////////////////////////////////////////////////////////////////
class MidLevelTable : public Table
{
private:
LastLevelTable *pTTL1; //linked list of L1 tables
public:
MidLevelTable() :Table()
{
pTTL1 = NULL;
}
MidLevelTable(GMM_PAGETABLEPool *Pool, int NodeIdx, SyncInfo Info) : MidLevelTable()
{
PoolElem = Pool;
BBInfo = Info;
PoolNodeIdx = NodeIdx;
}
~MidLevelTable()
{
if (pTTL1)
{
LastLevelTable* item = pTTL1;
while (item)
{
LastLevelTable* nextItem = item->Next();
delete item;
item = nextItem;
}
pTTL1 = NULL;
}
}
LastLevelTable* GetL1Table(GMM_GFX_SIZE_T L2eIdx, LastLevelTable** Prev = NULL)
{
LastLevelTable* pL1Tbl = pTTL1;
LastLevelTable* PrevL1Tbl = NULL;
while (pL1Tbl)
{
if (pL1Tbl->GetL2eIdx() == L2eIdx)
{
break;
}
PrevL1Tbl = pL1Tbl;
pL1Tbl = pL1Tbl->Next();
}
//if requested, save previous node in linked-list
if (Prev)
{
*Prev = PrevL1Tbl;
}
return pL1Tbl;
}
void InsertInList(LastLevelTable* pL1Tbl)
{
LastLevelTable* Prev = pTTL1;
//Insert at end
while (Prev && Prev->Next())
{
Prev = Prev->Next();
}
if (Prev)
{
Prev->Next() = pL1Tbl;
}
else
{
pTTL1 = pL1Tbl;
}
}
void DeleteFromList(LastLevelTable* pL1Tbl, LastLevelTable* PrevL1Tbl)
{
//Save next L1Table in list, before deleting current one
if (pL1Tbl)
{
if (PrevL1Tbl)
{
PrevL1Tbl->Next() = pL1Tbl->Next();
}
else
{
pTTL1 = pL1Tbl->Next();
}
delete pL1Tbl;
}
}
};
/////////////////////////////////////////////////////
/// Contains functions and members for PageTable.
/// PageTable defines multi-level pageTable
/////////////////////////////////////////////////////
class PageTable :
public GmmMemAllocator
{
protected:
const TT_TYPE TTType; //PageTable is AuxTT
const int NodesPerTable; //Aux L2/L3 has 32KB size, Aux L1 has 4KB -can't use as selector for PageTable is AuxTT
// 1 node for TR-table, 8 nodes for Aux-Table L2, 2 nodes for Aux-table L1
//Root Table structure
struct RootTable
{
GMM_RESOURCE_INFO* pGmmResInfo;
HANDLE L3Handle;
GMM_GFX_ADDRESS GfxAddress; //L3 Table Adr CPU equivalent GPU addr
GMM_GFX_ADDRESS CPUAddress; //LMEM-cpuvisible adr
bool NeedRegisterUpdate; //True @ L3 allocation, False when L3AdrRegWrite done
SyncInfo BBInfo;
RootTable() : pGmmResInfo(NULL), L3Handle(NULL), GfxAddress(0), CPUAddress(0), NeedRegisterUpdate(false), BBInfo() {}
} TTL3;
MidLevelTable* pTTL2; //array of L2-Tables
public:
#ifdef _WIN32
CRITICAL_SECTION TTLock; //synchronized access of PageTable obj
#elif defined __linux__
pthread_mutex_t TTLock;
#endif
GmmPageTableMgr* PageTableMgr;
GmmClientContext *pClientContext;
PageTable(int Size, int NumL3e, TT_TYPE flag) :
TTType(flag),
NodesPerTable(Size / PAGE_SIZE)
{
PageTableMgr = NULL;
pClientContext = NULL;
InitializeCriticalSection(&TTLock);
pTTL2 = new MidLevelTable[NumL3e];
}
~PageTable()
{
delete[] pTTL2;
DeleteCriticalSection(&TTLock);
}
inline GMM_LIB_CONTEXT* GetGmmLibContext()
{
return pClientContext->GetLibContext();
}
GMM_GFX_ADDRESS GetL3Address() { return TTL3.GfxAddress; }
bool &GetRegisterStatus() { return TTL3.NeedRegisterUpdate; }
GMM_STATUS AllocateL3Table(uint32_t L3TableSize, uint32_t L3AddrAlignment);
GMM_STATUS DestroyL3Table();
void AllocateL1L2Table(GMM_GFX_ADDRESS TileAddr, GMM_GFX_ADDRESS * L1TableAdr, GMM_GFX_ADDRESS * L2TableAdr);
void AllocateDummyTables(GmmLib::Table **L2Table, GmmLib::Table **L1Table);
void GetL1L2TableAddr(GMM_GFX_ADDRESS TileAddr, GMM_GFX_ADDRESS * L1TableAdr, GMM_GFX_ADDRESS* L2TableAdr);
uint8_t GetMappingType(GMM_GFX_ADDRESS GfxVA, GMM_GFX_SIZE_T Size, GMM_GFX_ADDRESS& LastAddr);
HANDLE GetL3Handle() { return TTL3.L3Handle; }
};
//////////////////////////////////////////////////////////////////////////////////////////////
/// Contains functions and members for AuxTable.
/// AuxTable defines PageTable for translating VA->AuxVA, ie defines page-walk to get address
/// of CCS-cacheline containing auxiliary data (compression tag, etc) for some resource
/////////////////////////////////////////////////////////////////////////////////////////////
class AuxTable : public PageTable
{
public:
const int L1Size;
Table* NullL2Table;
Table* NullL1Table;
GMM_GFX_ADDRESS NullCCSTile;
AuxTable() : PageTable(8 * PAGE_SIZE, GMM_AUX_L3_SIZE, TT_TYPE::AUXTT),
L1Size(2 * PAGE_SIZE)
{
NullL2Table = nullptr;
NullL1Table = nullptr;
NullCCSTile = 0;
}
GMM_STATUS InvalidateTable(GMM_UMD_SYNCCONTEXT * UmdContext, GMM_GFX_ADDRESS BaseAdr, GMM_GFX_SIZE_T Size, uint8_t DoNotWait);
GMM_STATUS MapValidEntry(GMM_UMD_SYNCCONTEXT *UmdContext, GMM_GFX_ADDRESS BaseAdr, GMM_GFX_SIZE_T BaseSize,
GMM_RESOURCE_INFO* BaseResInfo, GMM_GFX_ADDRESS AuxVA, GMM_RESOURCE_INFO* AuxResInfo, uint64_t PartialData, uint8_t DoNotWait);
GMM_STATUS MapNullCCS(GMM_UMD_SYNCCONTEXT *UmdContext, GMM_GFX_ADDRESS BaseAdr, GMM_GFX_SIZE_T Size, uint64_t PartialL1e, uint8_t DoNotWait);
GMM_AUXTTL1e CreateAuxL1Data(GMM_RESOURCE_INFO* BaseResInfo);
GMM_GFX_ADDRESS GMM_INLINE __GetCCSCacheline(GMM_RESOURCE_INFO* BaseResInfo, GMM_GFX_ADDRESS BaseAdr, GMM_RESOURCE_INFO* AuxResInfo,
GMM_GFX_ADDRESS AuxVA, GMM_GFX_SIZE_T AdrOffset);
};
typedef struct _GMM_DEVICE_ALLOC {
uint32_t Size;
uint32_t Alignment;
HANDLE Handle;
GMM_GFX_ADDRESS GfxVA;
GMM_GFX_ADDRESS CPUVA;
void * Priv;
HANDLE hCsr;
} GMM_DEVICE_ALLOC;
typedef struct _GMM_DEVICE_DEALLOC {
HANDLE Handle;
GMM_GFX_ADDRESS GfxVA;
void * Priv;
HANDLE hCsr;
} GMM_DEVICE_DEALLOC;
GMM_STATUS __GmmDeviceAlloc(GmmClientContext *pClientContext,
GMM_DEVICE_CALLBACKS_INT *pDeviceCbInt,
GMM_DEVICE_ALLOC *pAlloc);
GMM_STATUS __GmmDeviceDealloc(GMM_CLIENT ClientType,
GMM_DEVICE_CALLBACKS_INT *DeviceCb,
GMM_DEVICE_DEALLOC *pDealloc,
GmmClientContext *pClientContext);
}
#endif // #ifdef __cplusplus

View File

@ -0,0 +1,169 @@
# Copyright(c) 2017 Intel Corporation
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files(the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and / or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
set (EXE_NAME GMMULT)
set(GMMULT_HEADERS
GmmCachePolicyULT.h
GmmCommonULT.h
GmmMultiAdapterULT.h
GmmGen10CachePolicyULT.h
GmmGen10ResourceULT.h
GmmGen11CachePolicyULT.h
GmmGen11ResourceULT.h
GmmGen12ResourceULT.h
GmmGen12dGPUResourceULT.h
GmmGen12CachePolicyULT.h
GmmGen12dGPUCachePolicyULT.h
GmmGen9CachePolicyULT.h
GmmGen9ResourceULT.h
GmmResourceULT.h
GmmAuxTableULT.h
stdafx.h
targetver.h
)
set(GMMULT_SOURCES
GmmCachePolicyULT.cpp
GmmCommonULT.cpp
GmmMultiAdapterULT.cpp
GmmGen10CachePolicyULT.cpp
GmmGen10ResourceULT.cpp
GmmGen11CachePolicyULT.cpp
GmmGen12CachePolicyULT.cpp
GmmGen12dGPUCachePolicyULT.cpp
GmmGen11ResourceULT.cpp
GmmGen12ResourceULT.cpp
GmmGen12dGPUResourceULT.cpp
GmmGen9CachePolicyULT.cpp
GmmGen9ResourceULT.cpp
GmmResourceCpuBltULT.cpp
GmmResourceULT.cpp
GmmAuxTableULT.cpp
googletest/src/gtest-all.cc
GmmULT.cpp
)
source_group("Source Files\\Cache Policy" FILES
GmmCachePolicyULT.cpp
GmmGen9CachePolicyULT.cpp
GmmGen10CachePolicyULT.cpp
GmmGen11CachePolicyULT.cpp
GmmGen12CachePolicyULT.cpp
GmmGen12dGPUCachePolicyULT.cpp
)
source_group("Source Files\\Resource" FILES
GmmGen10ResourceULT.cpp
GmmGen11ResourceULT.cpp
GmmGen12ResourceULT.cpp
GmmGen12dGPUResourceULT.cpp
GmmGen9ResourceULT.cpp
GmmResourceCpuBltULT.cpp
GmmResourceULT.cpp
)
source_group("Source Files\\TranslationTable" FILES
GmmAuxTableULT.cpp
)
source_group("Source Files\\MultiAdapter" FILES
GmmMultiAdapterULT.cpp
)
source_group("Header Files\\TranslationTable" FILES
GmmAuxTableULT.h
)
source_group("Header Files\\Cache Policy" FILES
GmmCachePolicyULT.h
GmmGen10CachePolicyULT.h
GmmGen11CachePolicyULT.h
GmmGen12CachePolicyULT.h
GmmGen12dGPUCachePolicyULT.h
GmmGen9CachePolicyULT.h
)
source_group("Header Files\\Resource" FILES
GmmGen10ResourceULT.h
GmmGen11ResourceULT.h
GmmGen12ResourceULT.h
GmmGen12dGPUResourceULT.h
GmmGen9ResourceULT.h
GmmResourceULT.h
)
source_group("Header Files\\MultiAdapter" FILES
GmmMultiAdapterULT.h
)
source_group("gtest" FILES
googletest/gtest/gtest.h
googletest/src/gtest-all.cc
)
include_directories(BEFORE ./)
include_directories(BEFORE ${PROJECT_SOURCE_DIR})
include_directories(
googletest
googletest/gtest
${BS_DIR_INC}/umKmInc
${BS_DIR_INC}
${BS_DIR_GMMLIB}/inc
${BS_DIR_INC}/common
)
macro(GmmLibULTSetTargetConfig ultTarget)
if (TARGET ${ultTarget})
set_property(TARGET ${ultTarget} APPEND PROPERTY COMPILE_DEFINITIONS
$<$<CONFIG:Release>: _RELEASE>
$<$<CONFIG:ReleaseInternal>: _RELEASE_INTERNAL>
$<$<CONFIG:Debug>: _DEBUG>
)
endif()
endmacro()
add_executable(${EXE_NAME} ${GMMULT_HEADERS} ${GMMULT_SOURCES})
GmmLibULTSetTargetConfig(${EXE_NAME})
set_property(TARGET ${EXE_NAME} APPEND PROPERTY COMPILE_DEFINITIONS __GMM GMM_LIB_DLL __UMD)
if(NOT TARGET igfx_gmmumd_dll)
add_subdirectory("${BS_DIR_GMMLIB}" "${CMAKE_BINARY_DIR}/gmmlib/ult")
endif()
target_link_libraries(${EXE_NAME} igfx_gmmumd_dll)
target_link_libraries(${EXE_NAME}
pthread
dl
)
add_custom_target(Run_ULT ALL DEPENDS GMMULT)
add_custom_command(
TARGET Run_ULT
POST_BUILD
COMMAND echo running ULTs
COMMAND "${CMAKE_COMMAND}" -E env "LD_LIBRARY_PATH=$<TARGET_FILE_DIR:igfx_gmmumd_dll>" ${CMAKE_CFG_INTDIR}/${EXE_NAME} --gtest_filter=CTest*
)

View File

@ -0,0 +1,265 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#if defined (__linux__) && !defined(__i386__)
#include "GmmAuxTableULT.h"
using namespace std;
using namespace GmmLib;
static GMM_DEVICE_CALLBACKS_INT DeviceCBInt;
CTestAuxTable::CTestAuxTable()
{
}
CTestAuxTable::~CTestAuxTable()
{
}
int CTestAuxTable::allocCB(void *bufMgr, size_t size, size_t alignment, void **bo, void **cpuAddr, uint64_t *gpuAddr)
{
if(bufMgr != (void *)0xdeadbeef)
return -1;
if(!bo || !cpuAddr || !gpuAddr)
return -2;
*cpuAddr = aligned_alloc(alignment, ALIGN(size, alignment));
if(!*cpuAddr)
return -3;
*bo = *cpuAddr;
*gpuAddr = (uint64_t)*cpuAddr;
return 0;
}
void CTestAuxTable::freeCB(void *bo)
{
ASSERT_TRUE(bo != NULL);
free(bo);
}
void CTestAuxTable::waitFromCpuCB(void *bo)
{
}
void CTestAuxTable::SetUpTestCase()
{
GfxPlatform.eProductFamily = IGFX_TIGERLAKE_LP;
GfxPlatform.eRenderCoreFamily = IGFX_GEN12_CORE;
DeviceCBInt.pBufMgr = (void *)0xdeadbeef;
DeviceCBInt.DevCbPtrs_.pfnAllocate = CTestAuxTable::allocCB;
DeviceCBInt.DevCbPtrs_.pfnDeallocate = CTestAuxTable::freeCB;
DeviceCBInt.DevCbPtrs_.pfnWaitFromCpu = CTestAuxTable::waitFromCpuCB;
if(GfxPlatform.eProductFamily == IGFX_UNKNOWN ||
GfxPlatform.eRenderCoreFamily == IGFX_UNKNOWN_CORE)
{
GfxPlatform.eProductFamily = IGFX_BROADWELL;
GfxPlatform.eRenderCoreFamily = IGFX_GEN8_CORE;
}
AllocateAdapterInfo();
if(pGfxAdapterInfo)
{
pGfxAdapterInfo->SkuTable.FtrE2ECompression = true;
pGfxAdapterInfo->SkuTable.FtrLinearCCS = true;
}
CommonULT::SetUpTestCase();
}
void CTestAuxTable::TearDownTestCase()
{
CommonULT::TearDownTestCase();
}
TEST_F(CTestAuxTable, TestUpdateAuxTableCompressedSurface)
{
GmmPageTableMgr *mgr = pGmmULTClientContext->CreatePageTblMgrObject(&DeviceCBInt, TT_TYPE::AUXTT);
ASSERT_TRUE(mgr != NULL);
Surface *surf = new Surface(7680, 4320);
ASSERT_TRUE(surf != NULL && surf->init());
GMM_DDI_UPDATEAUXTABLE updateReq = {0};
updateReq.BaseResInfo = surf->getGMMResourceInfo();
updateReq.BaseGpuVA = surf->getGfxAddress(GMM_PLANE_Y);
updateReq.Map = 1;
GMM_STATUS res = mgr->UpdateAuxTable(&updateReq);
ASSERT_TRUE(res == GMM_SUCCESS);
delete surf;
pGmmULTClientContext->DestroyPageTblMgrObject(mgr);
}
TEST_F(CTestAuxTable, DISABLED_TestUpdateAuxTableNonCompressedSurface)
{
GmmPageTableMgr *mgr = pGmmULTClientContext->CreatePageTblMgrObject(&DeviceCBInt, TT_TYPE::AUXTT);
ASSERT_TRUE(mgr != NULL);
Surface *surf = new Surface(7680, 4320, false);
ASSERT_TRUE(surf != NULL && surf->init());
GMM_DDI_UPDATEAUXTABLE updateReq = {0};
memset(&updateReq, 0, sizeof(GMM_DDI_UPDATEAUXTABLE));
updateReq.BaseResInfo = surf->getGMMResourceInfo();
updateReq.BaseGpuVA = surf->getGfxAddress(GMM_PLANE_Y);
updateReq.Map = 1;
GMM_STATUS res = mgr->UpdateAuxTable(&updateReq);
ASSERT_TRUE(res != GMM_SUCCESS);
delete surf;
pGmmULTClientContext->DestroyPageTblMgrObject(mgr);
}
TEST_F(CTestAuxTable, TestInvalidateAuxTable)
{
GmmPageTableMgr *mgr = pGmmULTClientContext->CreatePageTblMgrObject(&DeviceCBInt, TT_TYPE::AUXTT);
ASSERT_TRUE(mgr != NULL);
Surface *surf = new Surface(7680, 4320);
ASSERT_TRUE(surf != NULL && surf->init());
GMM_DDI_UPDATEAUXTABLE updateReq = {0};
updateReq.BaseResInfo = surf->getGMMResourceInfo();
updateReq.BaseGpuVA = surf->getGfxAddress(GMM_PLANE_Y);
updateReq.Map = 1;
GMM_STATUS res = mgr->UpdateAuxTable(&updateReq);
ASSERT_TRUE(res == GMM_SUCCESS);
memset(&updateReq, 0, sizeof(updateReq));
updateReq.BaseResInfo = surf->getGMMResourceInfo();
updateReq.Map = 0;
res = mgr->UpdateAuxTable(&updateReq);
ASSERT_TRUE(res == GMM_SUCCESS);
delete surf;
pGmmULTClientContext->DestroyPageTblMgrObject(mgr);
}
TEST_F(CTestAuxTable, DISABLED_TestUpdateAuxTableStress)
{
const int num_surf = 1000;
Surface * surfaces[num_surf];
Surface * surf;
int i;
GmmPageTableMgr *mgr = pGmmULTClientContext->CreatePageTblMgrObject(&DeviceCBInt, TT_TYPE::AUXTT);
ASSERT_TRUE(mgr != NULL);
for(i = 0; i < num_surf; i++)
{
surf = new Surface(7680, 4320);
surfaces[i] = surf;
ASSERT_TRUE(surf != NULL && surf->init());
GMM_DDI_UPDATEAUXTABLE updateReq = {0};
updateReq.BaseResInfo = surf->getGMMResourceInfo();
updateReq.BaseGpuVA = surf->getGfxAddress(GMM_PLANE_Y);
updateReq.Map = 1;
mgr->UpdateAuxTable(&updateReq);
}
for(i = 0; i < num_surf; i++)
{
surf = surfaces[i];
delete surf;
}
pGmmULTClientContext->DestroyPageTblMgrObject(mgr);
}
TEST_F(CTestAuxTable, TestAuxTableContent)
{
GmmPageTableMgr *mgr = pGmmULTClientContext->CreatePageTblMgrObject(&DeviceCBInt, TT_TYPE::AUXTT);
ASSERT_TRUE(mgr != NULL);
Surface *surf = new Surface(720, 480);
ASSERT_TRUE(surf != NULL && surf->init());
GMM_DDI_UPDATEAUXTABLE updateReq = {0};
updateReq.BaseResInfo = surf->getGMMResourceInfo();
updateReq.BaseGpuVA = surf->getGfxAddress(GMM_PLANE_Y);
updateReq.Map = 1;
GMM_STATUS res = mgr->UpdateAuxTable(&updateReq);
ASSERT_TRUE(res == GMM_SUCCESS);
Walker *ywalker = new Walker(surf->getGfxAddress(GMM_PLANE_Y),
surf->getAuxGfxAddress(GMM_AUX_CCS),
mgr->GetAuxL3TableAddr());
for(size_t i = 0; i < surf->getSurfaceSize(GMM_PLANE_Y); i++)
{
GMM_GFX_ADDRESS addr = surf->getGfxAddress(GMM_PLANE_Y) + i;
GMM_GFX_ADDRESS val = ywalker->walk(addr);
GMM_GFX_ADDRESS expected = ywalker->expected(addr);
ASSERT_EQ(expected, val);
}
Walker *uvwalker = new Walker(surf->getGfxAddress(GMM_PLANE_U),
surf->getAuxGfxAddress(GMM_AUX_UV_CCS),
mgr->GetAuxL3TableAddr());
for(size_t i = 0; i < surf->getSurfaceSize(GMM_PLANE_U); i++)
{
GMM_GFX_ADDRESS addr = surf->getGfxAddress(GMM_PLANE_U) + i;
GMM_GFX_ADDRESS val = uvwalker->walk(addr);
GMM_GFX_ADDRESS expected = uvwalker->expected(addr);
ASSERT_EQ(expected, val);
}
delete uvwalker;
delete ywalker;
delete surf;
pGmmULTClientContext->DestroyPageTblMgrObject(mgr);
}
#endif /* __linux__ */

View File

@ -0,0 +1,252 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#if defined (__linux__) && !defined(__i386__)
#ifndef _ISOC11_SOURCE
#define _ISOC11_SOURCE 1
#endif
#include "GmmGen10ResourceULT.h"
#include <stdlib.h>
#include <malloc.h>
#ifndef ALIGN
#define ALIGN(v, a) (((v) + ((a)-1)) & ~((a)-1))
#endif
class CTestAuxTable : public CTestGen10Resource
{
public:
static void SetUpTestCase();
static void TearDownTestCase();
CTestAuxTable();
~CTestAuxTable();
static int allocCB(void *bufMgr, size_t size, size_t alignment, void **bo, void **cpuAddr, uint64_t *gpuAddr);
static void freeCB(void *bo);
static void waitFromCpuCB(void *bo);
class Surface
{
public:
Surface(unsigned int width, unsigned int height, bool mmc = true)
: mWidth(width), mHeight(height), mMMC(mmc), mResInfo(0), mBuf(0)
{
}
~Surface()
{
deinit();
}
bool init()
{
size_t size;
size_t alignment;
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.Format = GMM_FORMAT_NV12;
gmmParams.BaseWidth = mWidth;
gmmParams.BaseHeight = mHeight;
gmmParams.Depth = 0x1;
gmmParams.ArraySize = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.Flags.Info.MediaCompressed = mMMC ? 1 : 0;
//gmmParams.Flags.Gpu.CCS = mmc ? 1 : 0;
gmmParams.Flags.Gpu.MMC = mMMC ? 1 : 0;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.Flags.Gpu.RenderTarget = 1;
gmmParams.Flags.Gpu.UnifiedAuxSurface = mMMC ? 1 : 0;
//gmmParams.Flags.Gpu.Depth = 1;
gmmParams.Flags.Gpu.Video = true;
mResInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
size = mResInfo->GetSizeSurface();
alignment = mResInfo->GetResFlags().Info.TiledYf ? GMM_KBYTE(16) : GMM_KBYTE(64);
mBuf = aligned_alloc(alignment, ALIGN(size, alignment));
if(!mResInfo || !mBuf)
return false;
mYBase = (GMM_GFX_ADDRESS)mBuf;
mUVBase = 0;
mAuxYBase = mYBase + mResInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CCS);
mAuxUVBase = 0;
mYPlaneSize = mResInfo->GetSizeMainSurface();
if(pGmmULTClientContext->IsPlanar(mResInfo->GetResourceFormat()))
{
GMM_REQ_OFFSET_INFO ReqInfo = {0};
ReqInfo.Plane = GMM_PLANE_U;
ReqInfo.ReqRender = 1;
mResInfo->GetOffset(ReqInfo);
mYPlaneSize = ReqInfo.Render.Offset64;
mUVBase = mYBase + mYPlaneSize;
mAuxUVBase = mYBase + mResInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_UV_CCS);
}
mUVPlaneSize = mResInfo->GetSizeMainSurface() - mYPlaneSize;
return true;
}
void deinit()
{
if(mBuf)
{
free(mBuf);
mBuf = NULL;
}
if(mResInfo)
{
pGmmULTClientContext->DestroyResInfoObject(mResInfo);
mResInfo = NULL;
}
}
GMM_GFX_ADDRESS getGfxAddress(GMM_YUV_PLANE plane)
{
switch(plane)
{
case GMM_PLANE_Y:
return mYBase;
case GMM_PLANE_U:
case GMM_PLANE_V:
return mUVBase;
default:
throw;
}
}
GMM_GFX_ADDRESS getAuxGfxAddress(GMM_UNIFIED_AUX_TYPE auxType)
{
switch(auxType)
{
case GMM_AUX_CCS:
case GMM_AUX_Y_CCS:
return mAuxYBase;
case GMM_AUX_UV_CCS:
return mAuxUVBase;
default:
throw;
}
}
GMM_RESOURCE_INFO *getGMMResourceInfo()
{
return mResInfo;
}
size_t getSurfaceSize(GMM_YUV_PLANE plane)
{
switch(plane)
{
case GMM_PLANE_Y:
return mYPlaneSize;
case GMM_PLANE_U:
case GMM_PLANE_V:
return mUVPlaneSize;
default:
throw;
}
}
private:
unsigned int mWidth;
unsigned int mHeight;
bool mMMC;
GMM_RESOURCE_INFO *mResInfo;
void * mBuf;
GMM_GFX_ADDRESS mYBase;
GMM_GFX_ADDRESS mUVBase;
GMM_GFX_ADDRESS mAuxYBase;
GMM_GFX_ADDRESS mAuxUVBase;
size_t mYPlaneSize;
size_t mUVPlaneSize;
};
class Walker
{
public:
Walker(GMM_GFX_ADDRESS mainBase, GMM_GFX_ADDRESS auxBase,
GMM_GFX_ADDRESS l3Base)
{
mMainBase = mainBase;
mAuxBase = (auxBase >> 6) << 6;
mL3Base = (uint64_t *)l3Base;
}
GMM_GFX_ADDRESS expected(GMM_GFX_ADDRESS addr)
{
uint8_t Is64KChunk = (const_cast<WA_TABLE &>(pGfxAdapterInfo->WaTable).WaAuxTable16KGranular) ? 0 : 1;
uint32_t count = (addr - mMainBase) / (Is64KChunk ? GMM_KBYTE(64) : GMM_KBYTE(16));
return mAuxBase + (Is64KChunk ? 256 : 64) * count;
}
GMM_GFX_ADDRESS walk(GMM_GFX_ADDRESS addr)
{
uint64_t mask = (const_cast<WA_TABLE &>(pGfxAdapterInfo->WaTable).WaAuxTable16KGranular) ? 0x0000ffffffffffc0 : 0x0000ffffffffff00;
uint32_t idx = l3Index(addr);
uint64_t *l2Base = (uint64_t *)((mL3Base[idx] >> 15) << 15);
idx = l2Index(addr);
uint64_t *l1Base = (uint64_t *)((l2Base[idx] >> 13) << 13);
idx = l1Index(addr);
uint64_t auxAddr = (uint64_t)(l1Base[idx] & mask);
return auxAddr;
}
public:
static inline uint32_t l3Index(GMM_GFX_ADDRESS addr)
{
return GMM_AUX_L3_ENTRY_IDX(addr);
}
static inline uint32_t l2Index(GMM_GFX_ADDRESS addr)
{
return GMM_AUX_L2_ENTRY_IDX(addr);
}
static inline uint32_t l1Index(GMM_GFX_ADDRESS addr)
{
return GMM_AUX_L1_ENTRY_IDX_EXPORTED(addr, !(const_cast<WA_TABLE &>(pGfxAdapterInfo->WaTable).WaAuxTable16KGranular));
}
private:
GMM_GFX_ADDRESS mMainBase;
GMM_GFX_ADDRESS mAuxBase;
uint64_t * mL3Base;
};
};
#endif /* __linux__ */

View File

@ -0,0 +1,145 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmCachePolicyULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// Sets up common environment for Cache Policy fixture tests. this is called once per
/// test case before executing all tests under resource fixture test case.
/// It also calls SetupTestCase from CommonULT to initialize global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestCachePolicy::SetUpTestCase()
{
GfxPlatform.eProductFamily = IGFX_BROADWELL;
GfxPlatform.eRenderCoreFamily = IGFX_GEN8_CORE;
AllocateAdapterInfo();
pGfxAdapterInfo->SystemInfo.L3CacheSizeInKb = 768;
pGfxAdapterInfo->SystemInfo.LLCCacheSizeInKb = 2 * 1024; //2 MB
pGfxAdapterInfo->SystemInfo.EdramSizeInKb = 64 * 1024; //64 MB
const_cast<SKU_FEATURE_TABLE &>(pGfxAdapterInfo->SkuTable).FtrEDram = 1;
CommonULT::SetUpTestCase();
printf("%s\n", __FUNCTION__);
}
/////////////////////////////////////////////////////////////////////////////////////
/// cleans up once all the tests finish execution. It also calls TearDownTestCase
/// from CommonULT to destroy global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestCachePolicy::TearDownTestCase()
{
printf("%s\n", __FUNCTION__);
CommonULT::TearDownTestCase();
}
void CTestCachePolicy::CheckL3CachePolicy()
{
const uint32_t TargetCache_L3_LLC_ELLC = 0x3;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
MEMORY_OBJECT_CONTROL_STATE Mocs = ClientRequest.MemoryObjectOverride;
// Not check WT/WB/UC since that doesn't really matter for L3
if(ClientRequest.L3)
{
EXPECT_EQ(TargetCache_L3_LLC_ELLC, Mocs.Gen8.TargetCache) << "Usage# " << Usage << ": Incorrect L3 target cache setting";
}
}
}
TEST_F(CTestCachePolicy, TestL3CachePolicy)
{
CheckL3CachePolicy();
}
void CTestCachePolicy::CheckLlcEdramCachePolicy()
{
const uint32_t TargetCache_ELLC = 0;
const uint32_t TargetCache_LLC = 1;
const uint32_t TargetCache_LLC_ELLC = 2;
const uint32_t TargetCache_L3_LLC_ELLC = 2;
const uint32_t CC_UNCACHED = 0x1;
const uint32_t CC_CACHED_WT = 0x2;
const uint32_t CC_CACHED_WB = 0x3;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
MEMORY_OBJECT_CONTROL_STATE Mocs = ClientRequest.MemoryObjectOverride;
// Check for age
EXPECT_EQ(ClientRequest.AGE, Mocs.Gen8.Age) << "Usage# " << Usage << ": Incorrect AGE settings";
if(ClientRequest.L3)
{
continue;
}
if(!ClientRequest.LLC && !ClientRequest.ELLC) // Uncached
{
EXPECT_EQ(CC_UNCACHED, Mocs.Gen8.CacheControl) << "Usage# " << Usage << ": Incorrect cache control setting";
}
else
{
if(ClientRequest.WT) // Write-through
{
EXPECT_EQ(CC_CACHED_WT, Mocs.Gen8.CacheControl) << "Usage# " << Usage << ": Incorrect cache control setting";
}
else // Write-back
{
EXPECT_EQ(CC_CACHED_WB, Mocs.Gen8.CacheControl) << "Usage# " << Usage << ": Incorrect cache control setting";
}
if(ClientRequest.LLC && !ClientRequest.ELLC) // LLC only
{
EXPECT_EQ(TargetCache_LLC, Mocs.Gen8.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
}
else if(!ClientRequest.LLC && ClientRequest.ELLC) // eLLC only
{
EXPECT_EQ(TargetCache_ELLC, Mocs.Gen8.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
}
else if(ClientRequest.LLC && ClientRequest.ELLC)
{
EXPECT_EQ(TargetCache_LLC_ELLC, Mocs.Gen8.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
}
}
}
}
TEST_F(CTestCachePolicy, TestLlcEdramCachePolicy)
{
CheckLlcEdramCachePolicy();
}

View File

@ -0,0 +1,37 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmCommonULT.h"
// Base Class for Cache Policy Compile Time ULT
class CTestCachePolicy : public CommonULT
{
protected:
virtual void CheckL3CachePolicy();
virtual void CheckLlcEdramCachePolicy();
public:
static void SetUpTestCase();
static void TearDownTestCase();
};

View File

@ -0,0 +1,116 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmCommonULT.h"
#ifndef _WIN32
#include <dlfcn.h>
#endif
ADAPTER_INFO * CommonULT::pGfxAdapterInfo = NULL;
PLATFORM CommonULT::GfxPlatform = {};
GMM_CLIENT_CONTEXT *CommonULT::pGmmULTClientContext = NULL;
PFNGMMINIT CommonULT::pfnGmmInit = {0};
PFNGMMDESTROY CommonULT::pfnGmmDestroy = {0};
#ifdef _WIN32
HINSTANCE CommonULT::hGmmLib = NULL;
#else
void *CommonULT::hGmmLib = NULL;
#endif
void CommonULT::AllocateAdapterInfo()
{
if(!pGfxAdapterInfo)
{
pGfxAdapterInfo = (ADAPTER_INFO *)malloc(sizeof(ADAPTER_INFO));
if(!pGfxAdapterInfo)
{
ASSERT_TRUE(false);
return;
}
memset(pGfxAdapterInfo, 0, sizeof(ADAPTER_INFO));
pGfxAdapterInfo->SkuTable.FtrTileY = 1;
}
}
void CommonULT::SetUpTestCase()
{
printf("%s\n", __FUNCTION__);
GMM_INIT_IN_ARGS InArgs;
GMM_INIT_OUT_ARGS OutArgs;
if(GfxPlatform.eProductFamily == IGFX_UNKNOWN ||
GfxPlatform.eRenderCoreFamily == IGFX_UNKNOWN_CORE)
{
GfxPlatform.eProductFamily = IGFX_BROADWELL;
GfxPlatform.eRenderCoreFamily = IGFX_GEN8_CORE;
}
AllocateAdapterInfo();
InArgs.ClientType = GMM_EXCITE_VISTA;
InArgs.pGtSysInfo = &pGfxAdapterInfo->SystemInfo;
InArgs.pSkuTable = &pGfxAdapterInfo->SkuTable;
InArgs.pWaTable = &pGfxAdapterInfo->WaTable;
InArgs.Platform = GfxPlatform;
#ifdef _WIN32
InArgs.stAdapterBDF = {0, 2, 0, 0};
#endif
hGmmLib = dlopen(GMM_UMD_DLL, RTLD_LAZY);
ASSERT_TRUE(hGmmLib);
*(void **)(&pfnGmmInit) = dlsym(hGmmLib, "InitializeGmm");
*(void **)(&pfnGmmDestroy) = dlsym(hGmmLib, "GmmAdapterDestroy");
ASSERT_TRUE(pfnGmmInit);
ASSERT_TRUE(pfnGmmDestroy);
pfnGmmInit(&InArgs, &OutArgs);
pGmmULTClientContext = OutArgs.pGmmClientContext;
ASSERT_TRUE(pGmmULTClientContext);
}
void CommonULT::TearDownTestCase()
{
printf("%s\n", __FUNCTION__);
GMM_INIT_OUT_ARGS OutArgs;
OutArgs.pGmmClientContext = static_cast<GMM_CLIENT_CONTEXT *>(pGmmULTClientContext);
pfnGmmDestroy(&OutArgs);
if(hGmmLib)
{
dlclose(hGmmLib);
}
hGmmLib = NULL;
pGmmULTClientContext = NULL;
free(pGfxAdapterInfo);
pGfxAdapterInfo = NULL;
GfxPlatform = {};
}

View File

@ -0,0 +1,51 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "stdafx.h"
typedef GMM_STATUS (GMM_STDCALL *PFNGMMINIT)(GMM_INIT_IN_ARGS *pInArgs, GMM_INIT_OUT_ARGS *pOutArgs);
typedef void(GMM_STDCALL *PFNGMMDESTROY)(GMM_INIT_OUT_ARGS *pInArgs);
class CommonULT : public testing::Test
{
public:
static void SetUpTestCase();
static void TearDownTestCase();
static void AllocateAdapterInfo();
protected:
static ADAPTER_INFO *pGfxAdapterInfo;
static PLATFORM GfxPlatform;
static GMM_CLIENT_CONTEXT *pGmmULTClientContext;
static PFNGMMINIT pfnGmmInit;
static PFNGMMDESTROY pfnGmmDestroy;
#ifdef _WIN32
static HINSTANCE hGmmLib;
#else
static void *hGmmLib;
#endif
};

View File

@ -0,0 +1,33 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmGen10CachePolicyULT.h"
using namespace std;
TEST_F(CTestGen10CachePolicy, TestCachePolicyOverrides)
{
}
TEST_F(CTestGen10CachePolicy, TestCachePolicyConditionals)
{
}

View File

@ -0,0 +1,30 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmGen9CachePolicyULT.h"
class CTestGen10CachePolicy : public CTestGen9CachePolicy
{
};

View File

@ -0,0 +1,225 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmGen10ResourceULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// Sets up common environment for Resource fixture tests. this is called once per
/// test case before executing all tests under resource fixture test case.
// It also calls SetupTestCase from CommonULT to initialize global context and others.
///
/// @see CTestGen9Resource::SetUpTestCase()
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen10Resource::SetUpTestCase()
{
printf("%s\n", __FUNCTION__);
GfxPlatform.eProductFamily = IGFX_CANNONLAKE;
GfxPlatform.eRenderCoreFamily = IGFX_GEN10_CORE;
CommonULT::SetUpTestCase();
}
/////////////////////////////////////////////////////////////////////////////////////
/// cleans up once all the tests finish execution. It also calls TearDownTestCase
/// from CommonULT to destroy global context and others.
///
/// @see CTestGen10Resource::TearDownTestCase()
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen10Resource::TearDownTestCase()
{
printf("%s\n", __FUNCTION__);
CommonULT::TearDownTestCase();
}
/// @brief ULT for 2D TileYs Resource
TEST_F(CTestGen10Resource, Test2DTileYsResource)
{
printf("%s\n", __FUNCTION__);
}
/// @brief ULT for 2D TileYf Resource
TEST_F(CTestGen10Resource, Test2DTileYfResource)
{
printf("%s\n", __FUNCTION__);
}
TEST_F(CTestGen10Resource, TestMSAA)
{
//Tile dimensions in Bytes
const uint32_t MCSTileSize[1][2] = {128, 32}; //MCS is TileY
//Gen9: MSAA 16x no MCS for width > 8K
//No MSAA for YUV/compressed formats
//Interleaved MSS (IMS) for Depth/Stencil. Arrayed MSS (CMS) for Color RT
//MSS (Arrayed): px_wL, px_hL = pixel width/height of single sample at Lod L
// MSS width = px_wL, MSS height = NumSamples*px_hL
//MSS (Interleaved): px_wL, px_hL = pixel width/height of single sample at Lod L
// Samples MSS width MSS Height
// 2x 4*ceil(px_wL/2) px_hL
// 4x 4*ceil(px_wL/2) 4*ceil(px_hL/2)
// 8x 8*ceil(px_wL/2) 4*ceil(px_hL/2)
// 16x 8*ceil(px_wL/2) 8*ceil(px_hL/2)
//MCS (bpp): 2x/4x - bpp_8, 8x - bpp_32, 16x - bpp_64
const uint32_t TestDimensions[4][2] = {
//Input dimensions in #Tiles
{15, 20}, //16 Tiles x 20 <Max Width: Depth MSS crosses Pitch limit beyond this>
{0, 0}, //1x1x1
{1, 0}, //2 Tilesx1
{1, 1}, //2 Tiles x 2
};
uint32_t TestArraySize[2] = {1, 5};
uint32_t MinPitch = 32;
uint32_t HAlign = 0, VAlign = 0;
uint32_t TileDimX = 0, TileDimY = 0;
uint32_t MCSHAlign = 0, MCSVAlign = 0, TileSize = 0;
uint32_t ExpectedMCSBpp = 0;
std::vector<tuple<int, int, int, bool, int, int>> List; //TEST_TILE_TYPE, TEST_BPP, TEST_RESOURCE_TYPE, Depth or RT, TestDimension index, ArraySize
auto Size = BuildInputIterator(List, 4, 2); // Size of arrays TestDimensions, TestArraySize
for(auto element : List)
{
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Flags.Info = {0};
TEST_TILE_TYPE Tiling = (TEST_TILE_TYPE)std::get<0>(element);
TEST_BPP Bpp = (TEST_BPP)std::get<1>(element);
TEST_RESOURCE_TYPE ResType = (TEST_RESOURCE_TYPE)std::get<2>(element);
bool IsRT = std::get<3>(element); // True for RT, False for Depth
int TestDimIdx = std::get<4>(element); //index into TestDimensions array
int ArrayIdx = std::get<5>(element); //index into TestArraySize
TileSize = (Tiling == TEST_TILEYS) ? GMM_KBYTE(64) : GMM_KBYTE(4);
//Discard un-supported Tiling/Res_type/bpp for this test
if(ResType != TEST_RESOURCE_2D || //No 1D/3D/Cube. Supported 2D mip-maps/array
(!IsRT && (Tiling == TEST_TILEX ||
!(Bpp == TEST_BPP_16 || Bpp == TEST_BPP_32)))) //depth supported on 16bit, 32bit formats only
continue;
SetTileFlag(gmmParams, Tiling);
SetResType(gmmParams, ResType);
SetResGpuFlags(gmmParams, IsRT);
SetResArraySize(gmmParams, TestArraySize[ArrayIdx]);
gmmParams.NoGfxMemory = 1;
gmmParams.Format = SetResourceFormat(Bpp);
for(uint32_t k = MSAA_2x; k <= MSAA_16x; k++)
{
GetAlignmentAndTileDimensionsForMSAA(Bpp, IsRT, Tiling, (TEST_MSAA)k,
TileDimX, TileDimY, HAlign, VAlign,
ExpectedMCSBpp, MCSHAlign, MCSVAlign);
gmmParams.BaseWidth64 = TestDimensions[TestDimIdx][0] * TileDimX + 0x1;
gmmParams.BaseHeight = TestDimensions[TestDimIdx][1] * TileDimY + 0x1;
gmmParams.Depth = 0x1;
gmmParams.MSAA.NumSamples = static_cast<uint32_t>(pow((double)2, k));
gmmParams.Flags.Gpu.MCS = 0;
//MSS surface
GMM_RESOURCE_INFO *MSSResourceInfo;
MSSResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
if(MSSResourceInfo)
{
VerifyResourceHAlign<true>(MSSResourceInfo, HAlign);
VerifyResourceVAlign<true>(MSSResourceInfo, VAlign);
if(IsRT) //Arrayed MSS
{
uint32_t ExpectedPitch = 0, ExpectedQPitch = 0;
ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64, HAlign) * (uint32_t)pow(2.0, Bpp), TileDimX); // Aligned width * bpp, aligned to TileWidth
ExpectedPitch = GFX_MAX(ExpectedPitch, MinPitch);
VerifyResourcePitch<true>(MSSResourceInfo, ExpectedPitch);
if(Tiling != TEST_LINEAR)
VerifyResourcePitchInTiles<true>(MSSResourceInfo, ExpectedPitch / TileDimX);
ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, VAlign);
if(gmmParams.ArraySize > 1) //Gen9: Qpitch is distance between array slices (not sample slices)
{
VerifyResourceQPitch<true>(MSSResourceInfo, ExpectedQPitch);
}
uint32_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.MSAA.NumSamples * gmmParams.ArraySize, TileDimY); //Align Height =ExpectedPitch * NumSamples * ExpectedQPitch, to Tile-Height
VerifyResourceSize<true>(MSSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, TileSize));
}
else // Interleaved MSS
{
uint32_t WidthMultiplier, HeightMultiplier;
GetInterleaveMSSPattern((TEST_MSAA)k, WidthMultiplier, HeightMultiplier);
gmmParams.BaseWidth64 = WidthMultiplier > 1 ? GMM_ULT_ALIGN(gmmParams.BaseWidth64, 2) : gmmParams.BaseWidth64;
gmmParams.BaseHeight = HeightMultiplier > 1 ? GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) : gmmParams.BaseHeight;
uint32_t ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64 * WidthMultiplier, HAlign) * (uint32_t)pow(2.0, Bpp), TileDimX);
VerifyResourcePitch<true>(MSSResourceInfo, ExpectedPitch);
if(Tiling != TEST_LINEAR)
{
VerifyResourcePitchInTiles<true>(MSSResourceInfo, ExpectedPitch / TileDimX);
}
uint64_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight * HeightMultiplier, VAlign);
if(gmmParams.ArraySize > 1)
{
VerifyResourceQPitch<true>(MSSResourceInfo, ExpectedQPitch);
}
uint64_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize, TileDimY); //Align Height = ExpectedQPitch*ArraySize, to Tile-Height
VerifyResourceSize<true>(MSSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, TileSize)); //ExpectedPitch *ExpectedHeight
}
}
//No MCS surface if MSS creation failed
if(MSSResourceInfo)
{
gmmParams.Flags.Gpu.MCS = 1;
GMM_RESOURCE_INFO *MCSResourceInfo;
MCSResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
VerifyResourceHAlign<true>(MCSResourceInfo, MCSHAlign);
VerifyResourceVAlign<true>(MCSResourceInfo, MCSVAlign);
uint32_t ExpectedPitch = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseWidth64, MCSHAlign) * ExpectedMCSBpp, MCSTileSize[0][0]); // Align in texels, tehn multiply w/ Bpt
VerifyResourcePitch<true>(MCSResourceInfo, ExpectedPitch);
VerifyResourcePitchInTiles<true>(MCSResourceInfo, ExpectedPitch / MCSTileSize[0][0]);
uint32_t ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, MCSVAlign);
if(gmmParams.ArraySize > 1)
{
ExpectedQPitch = GMM_ULT_ALIGN(gmmParams.BaseHeight, MCSVAlign); //QPitch only for array
VerifyResourceQPitch<true>(MCSResourceInfo, ExpectedQPitch);
}
uint32_t ExpectedHeight = GMM_ULT_ALIGN(ExpectedQPitch * gmmParams.ArraySize, MCSTileSize[0][1]);
VerifyResourceSize<true>(MCSResourceInfo, GMM_ULT_ALIGN(ExpectedPitch * ExpectedHeight, GMM_KBYTE(4))); //MCS Tile is TileY
pGmmULTClientContext->DestroyResInfoObject(MCSResourceInfo);
} //MCS
pGmmULTClientContext->DestroyResInfoObject(MSSResourceInfo);
} //NumSamples = k
} //Iterate through all Input types
//Mip-mapped, MSAA case:
}

View File

@ -0,0 +1,32 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmGen9ResourceULT.h"
class CTestGen10Resource : public CTestGen9Resource
{
public:
static void SetUpTestCase();
static void TearDownTestCase();
};

View File

@ -0,0 +1,189 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmGen11CachePolicyULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// Sets up common environment for Cache Policy fixture tests. this is called once per
/// test case before executing all tests under resource fixture test case.
/// It also calls SetupTestCase from CommonULT to initialize global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen11CachePolicy::SetUpTestCase()
{
GfxPlatform.eProductFamily = IGFX_ICELAKE;
GfxPlatform.eRenderCoreFamily = IGFX_GEN11_CORE;
AllocateAdapterInfo();
pGfxAdapterInfo->SystemInfo.L3CacheSizeInKb = 3072;
pGfxAdapterInfo->SystemInfo.LLCCacheSizeInKb = 2 * 1024; //2 MB
pGfxAdapterInfo->SystemInfo.EdramSizeInKb = 128 * 1024; //128 MB
const_cast<SKU_FEATURE_TABLE &>(pGfxAdapterInfo->SkuTable).FtrEDram = 1;
CommonULT::SetUpTestCase();
printf("%s\n", __FUNCTION__);
}
/////////////////////////////////////////////////////////////////////////////////////
/// cleans up once all the tests finish execution. It also calls TearDownTestCase
/// from CommonULT to destroy global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen11CachePolicy::TearDownTestCase()
{
printf("%s\n", __FUNCTION__);
CommonULT::TearDownTestCase();
}
void CTestGen11CachePolicy::CheckL3CachePolicy()
{
const uint32_t L3_WB_CACHEABLE = 0x3;
const uint32_t L3_UNCACHEABLE = 0x1;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
uint32_t AssignedMocsIdx = ClientRequest.MemoryObjectOverride.Gen11.Index;
GMM_CACHE_POLICY_TBL_ELEMENT Mocs = pGmmULTClientContext->GetCachePolicyTlbElement(AssignedMocsIdx);
EXPECT_EQ(0, Mocs.L3.ESC) << "Usage# " << Usage << ": ESC is non-zero";
EXPECT_EQ(0, Mocs.L3.SCC) << "Usage# " << Usage << ": SCC is non-zero";
EXPECT_EQ(0, Mocs.L3.Reserved) << "Usage# " << Usage << ": Reserved field is non-zero";
// Check if Mocs Index is not greater than GMM_GEN9_MAX_NUMBER_MOCS_INDEXES
EXPECT_GT(GMM_MAX_NUMBER_MOCS_INDEXES, AssignedMocsIdx) << "Usage# " << Usage << ": MOCS Index greater than MAX allowed (62)";
// Check of assigned Index setting is appropriate for HDCL1 setting
if(ClientRequest.HDCL1)
{
EXPECT_GE(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
else
{
if(Usage == GMM_RESOURCE_USAGE_MOCS_62)
{
EXPECT_EQ(AssignedMocsIdx, 62) << "Usage# " << Usage << ": Incorrect Index for MOCS62 usage";
}
else if(Usage == GMM_RESOURCE_USAGE_L3_EVICTION)
{
EXPECT_EQ(AssignedMocsIdx, 63) << "Usage# " << Usage << ": Incorrect Index for MOCS63 usage";
}
else
{
EXPECT_LT(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
}
if(ClientRequest.L3)
{
EXPECT_EQ(L3_WB_CACHEABLE, Mocs.L3.Cacheability) << "Usage# " << Usage << ": Incorrect L3 cachebility setting";
}
else
{
EXPECT_EQ(L3_UNCACHEABLE, Mocs.L3.Cacheability) << "Usage# " << Usage << ": Incorrect L3 cachebility setting";
}
}
}
TEST_F(CTestGen11CachePolicy, TestL3CachePolicy)
{
CheckL3CachePolicy();
}
void CTestGen11CachePolicy::CheckLlcEdramCachePolicy()
{
const uint32_t TargetCache_LLC = 1;
const uint32_t LeCC_UNCACHEABLE = 0x1;
const uint32_t LeCC_WB_CACHEABLE = 0x3;
const uint32_t LeCC_WT_CACHEABLE = 0x2;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
uint32_t AssignedMocsIdx = ClientRequest.MemoryObjectOverride.Gen11.Index;
GMM_CACHE_POLICY_TBL_ELEMENT Mocs = pGmmULTClientContext->GetCachePolicyTlbElement(AssignedMocsIdx);
// Check for unused fields
EXPECT_EQ(0, Mocs.LeCC.AOM) << "Usage# " << Usage << ": AOM is non-zero";
EXPECT_EQ(0, Mocs.LeCC.CoS) << "Usage# " << Usage << ": CoS is non-zero";
EXPECT_EQ(0, Mocs.LeCC.PFM) << "Usage# " << Usage << ": PFM is non-zero";
EXPECT_EQ(0, Mocs.LeCC.SCC) << "Usage# " << Usage << ": SCC is non-zero";
EXPECT_EQ(0, Mocs.LeCC.SCF) << "Usage# " << Usage << ": SCF is non-zero";
EXPECT_EQ(0, Mocs.LeCC.ESC) << "Usage# " << Usage << ": ESC is non-zero";
EXPECT_EQ(0, Mocs.LeCC.Reserved) << "Usage# " << Usage << ": Reserved field is non-zero";
// Check for age
EXPECT_EQ(ClientRequest.AGE, Mocs.LeCC.LRUM) << "Usage# " << Usage << ": Incorrect AGE settings";
// Check for Snoop Setting
EXPECT_EQ(ClientRequest.SSO, Mocs.LeCC.SelfSnoop) << "Usage# " << Usage << ": Self Snoop is non-zero";
// Check if Mocs Index is not greater than GMM_GEN9_MAX_NUMBER_MOCS_INDEXES
EXPECT_GT(GMM_MAX_NUMBER_MOCS_INDEXES, AssignedMocsIdx) << "Usage# " << Usage << ": MOCS Index greater than MAX allowed (62)";
// Check of assigned Index setting is appropriate for HDCL1 setting
if(ClientRequest.HDCL1)
{
EXPECT_GE(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
else
{
if(Usage == GMM_RESOURCE_USAGE_MOCS_62)
{
EXPECT_EQ(AssignedMocsIdx, 62) << "Usage# " << Usage << ": Incorrect Index for MOCS62 usage";
}
else if(Usage == GMM_RESOURCE_USAGE_L3_EVICTION)
{
EXPECT_EQ(AssignedMocsIdx, 63) << "Usage# " << Usage << ": Incorrect Index for MOCS63 usage";
}
else
{
EXPECT_LT(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
}
if(ClientRequest.LLC) // LLC only
{
EXPECT_EQ(TargetCache_LLC, Mocs.LeCC.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
EXPECT_EQ(LeCC_WB_CACHEABLE, Mocs.LeCC.Cacheability) << "Usage# " << Usage << ": Incorrect LLC/eDRAM cachebility setting";
}
else
{
EXPECT_EQ(LeCC_UNCACHEABLE, Mocs.LeCC.Cacheability) << "Usage# " << Usage << ": Incorrect LLC cachebility setting";
}
}
}
TEST_F(CTestGen11CachePolicy, TestLlcEdramCachePolicy)
{
CheckLlcEdramCachePolicy();
}

View File

@ -0,0 +1,37 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmCachePolicyULT.h"
class CTestGen11CachePolicy : public CTestCachePolicy
{
protected:
virtual void CheckL3CachePolicy();
virtual void CheckLlcEdramCachePolicy();
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
#pragma once

View File

@ -0,0 +1,720 @@
/*==============================================================================
Copyright(c) 2016 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmGen11ResourceULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// Sets up common environment for Resource fixture tests. this is called once per
/// test case before executing all tests under resource fixture test case.
// It also calls SetupTestCase from CommonULT to initialize global context and others.
///
/// @see CTestGen9Resource::SetUpTestCase()
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen11Resource::SetUpTestCase()
{
printf("%s\n", __FUNCTION__);
GfxPlatform.eProductFamily = IGFX_LAKEFIELD;
GfxPlatform.eRenderCoreFamily = IGFX_GEN11_CORE;
CommonULT::SetUpTestCase();
}
/////////////////////////////////////////////////////////////////////////////////////
/// cleans up once all the tests finish execution. It also calls TearDownTestCase
/// from CommonULT to destroy global context and others.
///
/// @see CTestGen10Resource::TearDownTestCase()
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen11Resource::TearDownTestCase()
{
printf("%s\n", __FUNCTION__);
CommonULT::TearDownTestCase();
}
/// @brief ULT for 2D TileYs Resource
TEST_F(CTestGen11Resource, TestPlanar2D_NV12_MediaCompressed)
{
/* Test planar surface with hybrid UV planes where UV plane is half the size
of Y and U/V data is packed together */
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// [UV-Packing]
// YccsYccsYccs
// YccsYccsYccs
// UVccsUVccsUVccs
// UVccsUVccsUVccs
const uint32_t TileSize[2] = {128, 32}; // TileY
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Gpu.MMC = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.BaseWidth64 = 0x2048; //8264
gmmParams.BaseHeight = 0x274; // 628
gmmParams.Depth = 0x1;
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(TEST_TILEY));
gmmParams.Format = GMM_FORMAT_NV12;
GMM_RESOURCE_INFO *ResourceInfo;
//__debugbreak();
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[0]);
uint32_t Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]) +
GMM_ULT_ALIGN(gmmParams.BaseHeight / 2, TileSize[1]);
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
VerifyResourcePitch<true>(ResourceInfo, Pitch);
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[0]);
VerifyResourceSize<true>(ResourceInfo, Size);
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
// Y plane should be at 0,0
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
// U/V plane should be at end of Y plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
// Y Plane CCS should be at the end of NV12 surface.
EXPECT_EQ(Size, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CCS));
EXPECT_EQ(Size, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_Y_CCS));
// UV Plane CCS offset
uint32_t YCcsSize = GMM_ULT_ALIGN(((GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]) * Pitch) / 1024), PAGE_SIZE);
EXPECT_EQ(Size + YCcsSize, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_UV_CCS));
uint32_t UVCcsSize = GMM_ULT_ALIGN((Height - GFX_ALIGN(gmmParams.BaseHeight, TileSize[1])) * Pitch / 1024, PAGE_SIZE);
uint32_t MediaStateOffset = Size + YCcsSize + UVCcsSize;
EXPECT_EQ(MediaStateOffset, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_COMP_STATE));
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
TEST_F(CTestGen11Resource, TestPlanar2D_NV12_MediaCompressedArray)
{
/* Test planar surface with hybrid UV planes where UV plane is half the size
of Y and U/V data is packed together */
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// [UV-Packing]
// YccsYccsYccs
// YccsYccsYccs
// UVccsUVccsUVccs
// UVccsUVccsUVccs
// ...
const uint32_t TileSize[2] = {128, 32}; // TileY
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Gpu.MMC = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
gmmParams.Flags.Info.TiledY = 1;
gmmParams.BaseWidth64 = 0x2048;
gmmParams.BaseHeight = 0x274;
gmmParams.Depth = 0x1;
gmmParams.ArraySize = 20;
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(TEST_TILEY));
gmmParams.Format = GMM_FORMAT_NV12;
GMM_RESOURCE_INFO *ResourceInfo;
//__debugbreak();
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[0]);
uint32_t Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]) +
GMM_ULT_ALIGN(gmmParams.BaseHeight / 2, TileSize[1]);
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4)) * gmmParams.ArraySize;
VerifyResourcePitch<true>(ResourceInfo, Pitch);
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[0]);
VerifyResourceSize<true>(ResourceInfo, Size);
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
// Y plane should be at 0,0
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
// U/V plane should be at end of Y plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
// Y Plane CCS should be at the end of NV12 surface.
EXPECT_EQ(Size, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_CCS));
EXPECT_EQ(Size, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_Y_CCS));
// UV Plane CCS offset
uint32_t YCcsSize = GMM_ULT_ALIGN(((GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[1]) * Pitch) / 1024), PAGE_SIZE);
EXPECT_EQ(Size + YCcsSize, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_UV_CCS));
uint32_t UVCcsSize = GMM_ULT_ALIGN((Height - GFX_ALIGN(gmmParams.BaseHeight, TileSize[1])) * Pitch / 1024, PAGE_SIZE);
uint32_t MediaStateOffset = Size + YCcsSize + UVCcsSize;
EXPECT_EQ(MediaStateOffset, ResourceInfo->GetUnifiedAuxSurfaceOffset(GMM_AUX_COMP_STATE));
uint32_t AuxSize = YCcsSize + UVCcsSize + PAGE_SIZE;
EXPECT_EQ(AuxSize * gmmParams.ArraySize, ResourceInfo->GetSizeAuxSurface(GMM_AUX_CCS));
for(int i = 0; i < gmmParams.ArraySize; i++)
{
EXPECT_EQ(Size + AuxSize * i, ResourceInfo->GetPlanarAuxOffset(i, GMM_AUX_Y_CCS));
EXPECT_EQ(Size + (AuxSize * i) + YCcsSize, ResourceInfo->GetPlanarAuxOffset(i, GMM_AUX_UV_CCS));
EXPECT_EQ(Size + (AuxSize * i) + (YCcsSize + UVCcsSize), ResourceInfo->GetPlanarAuxOffset(i, GMM_AUX_COMP_STATE));
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
/// @brief ULT for 2D TileYf Resource
TEST_F(CTestGen11Resource, Test2DTileYfResource)
{
printf("%s\n", __FUNCTION__);
}
/// @brief ULT for Plannar 2D Resource - RGBP
TEST_F(CTestGen11Resource, TestPlanar2D_RGBP)
{
/* Test planar surfaces where all planes are full-sized */
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUUUUU
// UUUUUUUU
// UUUUUUUU
// UUUUUUUU
// VVVVVVVV
// VVVVVVVV
// VVVVVVVV
// VVVVVVVV
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
const uint32_t PlaneRowAlignment = 16;
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
{512, 8}, // TileX
{128, 32}}; // TileY
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
{
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.BaseWidth64 = 0x101;
gmmParams.BaseHeight = 0x101;
gmmParams.Depth = 0x1;
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
gmmParams.Format = GMM_FORMAT_RGBP;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t Pitch, Height;
if(Tile != TEST_LINEAR)
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
//Since Tile alignment factor is greater than GMM_IMCx_PLANE_ROW_ALIGNMENT=16
Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
Height = GMM_ULT_ALIGN(Height, TileSize[TileIndex][1]) * 3 /*Y, U, V*/;
}
else
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
Height = gmmParams.BaseHeight * 3 /*Y, U, V*/;
}
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
VerifyResourcePitch<true>(ResourceInfo, Pitch);
if(Tile != TEST_LINEAR)
{
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
}
VerifyResourceSize<true>(ResourceInfo, Size);
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
// Y plane should be at 0,0
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
// U plane should be at end of Y plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
EXPECT_EQ(Height / 3, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
// V plane should be at end of U plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
EXPECT_EQ(2 * (Height / 3), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for Plannar 2D Resource - RGBP
TEST_F(CTestGen11Resource, TestPlanar2DCustom_RGBP)
{
/* Test planar surfaces where all planes are full-sized */
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUUUUU
// UUUUUUUU
// UUUUUUUU
// UUUUUUUU
// VVVVVVVV
// VVVVVVVV
// VVVVVVVV
// VVVVVVVV
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
const uint32_t PlaneRowAlignment = 16;
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
{512, 8}, // TileX
{128, 32}}; // TileY
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
{
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
GMM_RESCREATE_CUSTOM_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.BaseWidth64 = 0x101;
gmmParams.BaseHeight = GMM_ULT_ALIGN(0x101, PlaneRowAlignment);
SetTileFlag_Custom(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
gmmParams.Format = GMM_FORMAT_RGBP;
uint32_t Pitch, Height;
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment /* min16 rows*/) * 3 /*Y, U, V*/;
uint32_t Size = Pitch * Height;
gmmParams.Pitch = Pitch;
gmmParams.Size = Size;
gmmParams.PlaneOffset.X[GMM_PLANE_Y] = 0;
gmmParams.PlaneOffset.Y[GMM_PLANE_Y] = 0;
gmmParams.PlaneOffset.X[GMM_PLANE_U] = 0;
gmmParams.PlaneOffset.Y[GMM_PLANE_U] = Height / 3;
gmmParams.PlaneOffset.X[GMM_PLANE_V] = 0;
gmmParams.PlaneOffset.Y[GMM_PLANE_V] = 2 * (Height / 3);
gmmParams.NoOfPlanes = 3;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateCustomResInfoObject(&gmmParams);
VerifyResourcePitch<true>(ResourceInfo, Pitch);
if(Tile != TEST_LINEAR)
{
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
}
VerifyResourceSize<true>(ResourceInfo, Size);
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
// Y plane should be at 0,0
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
// U plane should be at end of Y plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
EXPECT_EQ(Height / 3, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
// V plane should be at end of U plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
EXPECT_EQ(2 * (Height / 3), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for Plannar 2D Resource - MFX_JPEG_YUV422V , IMC1, IMC3
TEST_F(CTestGen11Resource, TestPlanar2D_MFX_JPEG_YUV422V)
{
/* Test planar surfaces where both U and V are half the size of Y */
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUUUUU
// UUUUUUUU
// VVVVVVVV
// VVVVVVVV
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
const uint32_t PlaneRowAlignment = 16;
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
{512, 8}, // TileX
{128, 32}}; // TileY
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
{
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.BaseWidth64 = 0x101;
gmmParams.BaseHeight = 0x101;
gmmParams.Depth = 0x1;
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
gmmParams.Format = GMM_FORMAT_MFX_JPEG_YUV422V;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t Pitch, Height;
uint32_t YHeight, VHeight;
if(Tile != TEST_LINEAR)
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) / 2, PlaneRowAlignment);
VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]);
}
else
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 2) / 2, PlaneRowAlignment);
}
Height = YHeight + 2 * VHeight;
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
VerifyResourcePitch<true>(ResourceInfo, Pitch);
if(Tile != TEST_LINEAR)
{
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
}
VerifyResourceSize<true>(ResourceInfo, Size);
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
// Y plane should be at 0,0
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
// U plane should be at end of Y plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
// V plane should be at end of U plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
EXPECT_EQ(YHeight + VHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for Plannar 2D Resource - MFX_JPEG_YUV411R
TEST_F(CTestGen11Resource, TestPlanar2D_MFX_JPEG_YUV411R)
{
/* Test planar surfaces where both U and V are quarter the size of Y */
//YYYYYYYY
//YYYYYYYY
//YYYYYYYY
//YYYYYYYY
//UUUUUUUU
//VVVVVVVV
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
const uint32_t PlaneRowAlignment = 16;
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
{512, 8}, // TileX
{128, 32}}; // TileY
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
{
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.BaseWidth64 = 0x101;
gmmParams.BaseHeight = 0x101;
gmmParams.Depth = 0x1;
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
gmmParams.Format = GMM_FORMAT_MFX_JPEG_YUV411R_TYPE;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t Pitch, Height;
uint32_t YHeight, VHeight;
if(Tile != TEST_LINEAR)
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 4) / 4, PlaneRowAlignment);
VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]);
}
else
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
VHeight = GMM_ULT_ALIGN(GMM_ULT_ALIGN(gmmParams.BaseHeight, 4) / 4, PlaneRowAlignment);
}
Height = YHeight + 2 * VHeight;
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
VerifyResourcePitch<true>(ResourceInfo, Pitch);
if(Tile != TEST_LINEAR)
{
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
}
VerifyResourceSize<true>(ResourceInfo, Size);
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
// Y plane should be at 0,0
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
// U plane should be at end of Y plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
// V plane should be at end of U plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
EXPECT_EQ(YHeight + VHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for Plannar 2D Resource - NV12
TEST_F(CTestGen11Resource, TestPlanar2D_NV12)
{
/* Test planar surface with hybrid UV planes where UV plane is half the size
of Y and U/V data is packed together */
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// [UV-Packing]
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
{512, 8}, // TileX
{128, 32}}; // TileY
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
{
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.BaseWidth64 = 0x100;
gmmParams.BaseHeight = 0x100;
gmmParams.Depth = 0x1;
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
gmmParams.Format = GMM_FORMAT_NV12;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t Pitch, Height;
if(Tile != TEST_LINEAR)
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
Height = GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]) +
GMM_ULT_ALIGN(gmmParams.BaseHeight / 2, TileSize[TileIndex][1]);
}
else
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
Height = GMM_ULT_ALIGN(gmmParams.BaseHeight /*Y*/ + gmmParams.BaseHeight / 2 /*UV*/, TileSize[TileIndex][1]);
}
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
VerifyResourcePitch<true>(ResourceInfo, Pitch);
if(Tile != TEST_LINEAR)
{
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
}
VerifyResourceSize<true>(ResourceInfo, Size);
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
// Y plane should be at 0,0
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
// U/V plane should be at end of Y plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
if(Tile != TEST_LINEAR)
{
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
EXPECT_EQ(GMM_ULT_ALIGN(gmmParams.BaseHeight, TileSize[TileIndex][1]), ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
}
else
{
EXPECT_EQ(gmmParams.BaseHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
EXPECT_EQ(gmmParams.BaseHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}
/// @brief ULT for Planar 2D Resource - IMC4
TEST_F(CTestGen11Resource, TestPlanar2D_IMC4)
{
/* Test planar surface V surface is on the right of U */
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// YYYYYYYY
// UUUUVVVV
// UUUUVVVV
const TEST_TILE_TYPE TileTypes[] = {TEST_LINEAR, TEST_TILEX, TEST_TILEY};
const uint32_t PlaneRowAlignment = 16;
const uint32_t TileSize[3][2] = {{1, 1}, //Linear
{512, 8}, // TileX
{128, 32}}; // TileY
for(uint32_t TileIndex = 0; TileIndex < sizeof(TileTypes) / sizeof(TileTypes[0]); TileIndex++)
{
TEST_TILE_TYPE Tile = TileTypes[TileIndex];
GMM_RESCREATE_PARAMS gmmParams = {};
gmmParams.Type = RESOURCE_2D;
gmmParams.NoGfxMemory = 1;
gmmParams.Flags.Gpu.Texture = 1;
gmmParams.BaseWidth64 = 0x101;
gmmParams.BaseHeight = 0x101;
gmmParams.Depth = 0x1;
SetTileFlag(gmmParams, static_cast<TEST_TILE_TYPE>(Tile));
gmmParams.Format = GMM_FORMAT_IMC4;
GMM_RESOURCE_INFO *ResourceInfo;
ResourceInfo = pGmmULTClientContext->CreateResInfoObject(&gmmParams);
uint32_t Pitch, Height;
uint32_t YHeight, VHeight;
if(Tile != TEST_LINEAR)
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, TileSize[TileIndex][0]);
if(Pitch / TileSize[TileIndex][0] % 2)
{
Pitch += TileSize[TileIndex][0];
}
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
VHeight = YHeight / 2;
YHeight = GMM_ULT_ALIGN(YHeight, TileSize[TileIndex][1]);
VHeight = GMM_ULT_ALIGN(VHeight, TileSize[TileIndex][1]); // No need of PlaneRowAlignment since last plane
}
else
{
Pitch = GMM_ULT_ALIGN(gmmParams.BaseWidth64, GMM_BYTES(64));
YHeight = GMM_ULT_ALIGN(gmmParams.BaseHeight, PlaneRowAlignment);
VHeight = YHeight / 2;
}
Height = YHeight + VHeight;
uint32_t Size = GMM_ULT_ALIGN(Pitch * Height, GMM_KBYTE(4));
VerifyResourcePitch<true>(ResourceInfo, Pitch);
if(Tile != TEST_LINEAR)
{
VerifyResourcePitchInTiles<true>(ResourceInfo, Pitch / TileSize[TileIndex][0]);
}
VerifyResourceSize<true>(ResourceInfo, Size);
VerifyResourceHAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceVAlign<false>(ResourceInfo, 0); // Same as any other 2D surface -- tested elsewhere
VerifyResourceQPitch<false>(ResourceInfo, 0); // N/A for planar
// Y plane should be at 0,0
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_Y));
EXPECT_EQ(0, ResourceInfo->GetPlanarYOffset(GMM_PLANE_Y));
// U plane should be at end of Y plane
// V plane should be at end of U plane
EXPECT_EQ(0, ResourceInfo->GetPlanarXOffset(GMM_PLANE_U));
EXPECT_EQ(Pitch / 2, ResourceInfo->GetPlanarXOffset(GMM_PLANE_V));
if(Tile != TEST_LINEAR)
{
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
}
else
{
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_U));
EXPECT_EQ(YHeight, ResourceInfo->GetPlanarYOffset(GMM_PLANE_V));
}
pGmmULTClientContext->DestroyResInfoObject(ResourceInfo);
}
}

View File

@ -0,0 +1,31 @@
/*==============================================================================
Copyright(c) 2016 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmGen10ResourceULT.h"
class CTestGen11Resource : public CTestGen10Resource
{
public:
static void SetUpTestCase();
static void TearDownTestCase();
};

View File

@ -0,0 +1,238 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmGen12CachePolicyULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// Sets up common environment for Cache Policy fixture tests. this is called once per
/// test case before executing all tests under resource fixture test case.
/// It also calls SetupTestCase from CommonULT to initialize global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen12CachePolicy::SetUpTestCase()
{
GfxPlatform.eProductFamily = IGFX_TIGERLAKE_LP;
GfxPlatform.eRenderCoreFamily = IGFX_GEN12_CORE;
AllocateAdapterInfo();
pGfxAdapterInfo->SystemInfo.L3CacheSizeInKb = 3072;
const_cast<SKU_FEATURE_TABLE &>(pGfxAdapterInfo->SkuTable).FtrEDram = false;
const_cast<SKU_FEATURE_TABLE &>(pGfxAdapterInfo->SkuTable).FtrLLCBypass = 0;
CommonULT::SetUpTestCase();
printf("%s\n", __FUNCTION__);
}
/////////////////////////////////////////////////////////////////////////////////////
/// cleans up once all the tests finish execution. It also calls TearDownTestCase
/// from CommonULT to destroy global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen12CachePolicy::TearDownTestCase()
{
printf("%s\n", __FUNCTION__);
CommonULT::TearDownTestCase();
}
void CTestGen12CachePolicy::CheckL3CachePolicy()
{
const uint32_t L3_WB_CACHEABLE = 0x3;
const uint32_t L3_UNCACHEABLE = 0x1;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
uint32_t AssignedMocsIdx = ClientRequest.MemoryObjectOverride.Gen12.Index;
GMM_CACHE_POLICY_TBL_ELEMENT Mocs = pGmmULTClientContext->GetCachePolicyTlbElement(AssignedMocsIdx);
//printf("Usage: %d --> Index: [%d]\n", Usage, AssignedMocsIdx);
EXPECT_EQ(0, Mocs.L3.ESC) << "Usage# " << Usage << ": ESC is non-zero";
EXPECT_EQ(0, Mocs.L3.SCC) << "Usage# " << Usage << ": SCC is non-zero";
EXPECT_EQ(0, Mocs.L3.Reserved) << "Usage# " << Usage << ": Reserved field is non-zero";
// Check if Mocs Index is not greater than GMM_MAX_NUMBER_MOCS_INDEXES
EXPECT_GT(GMM_MAX_NUMBER_MOCS_INDEXES, AssignedMocsIdx) << "Usage# " << Usage << ": MOCS Index greater than MAX allowed (63)";
if(ClientRequest.L3Eviction == 0x2) //63
{
if((GMM_RESOURCE_USAGE_TYPE)Usage == GMM_RESOURCE_USAGE_L3_EVICTION)
{
EXPECT_EQ(AssignedMocsIdx, 63) << "Usage# " << Usage << ": Incorrect Index for L3Eviction type# " << ClientRequest.L3Eviction;
EXPECT_EQ(0, ClientRequest.L3) << "Usage# " << Usage << ": Incorrect L3 cacheability for L3Eviction type# " << ClientRequest.L3Eviction;
}
else
{
EXPECT_NE(AssignedMocsIdx, 63) << "Usage# " << Usage << ": Incorrect Index for L3Eviction type# " << ClientRequest.L3Eviction;
EXPECT_EQ(1, ClientRequest.L3) << "Usage# " << Usage << ": Incorrect L3 cacheability for L3Eviction type# " << ClientRequest.L3Eviction;
}
}
else if(ClientRequest.L3Eviction == 0x3) //61
{
EXPECT_EQ(AssignedMocsIdx, 61) << "Usage# " << Usage << ": Incorrect Index for L3Eviction type# " << ClientRequest.L3Eviction;
EXPECT_EQ(1, ClientRequest.L3) << "Usage# " << Usage << ": Incorrect L3 cacheability for L3Eviction type# " << ClientRequest.L3Eviction;
}
else if(Usage == GMM_RESOURCE_USAGE_CCS) //60
{
EXPECT_EQ(AssignedMocsIdx, 60) << "Usage# " << Usage << ": Incorrect Index for CCS";
EXPECT_EQ(0, ClientRequest.L3) << "Usage# " << Usage << ": Incorrect L3 cacheability for CCS";
}
else if(Usage == GMM_RESOURCE_USAGE_MOCS_62) //62
{
EXPECT_EQ(AssignedMocsIdx, 62) << "Usage# " << Usage << ": Incorrect Index for MOCS_62";
EXPECT_EQ(0, ClientRequest.L3) << "Usage# " << Usage << ": Incorrect L3 cacheability for MOCS#62";
}
// Check of assigned Index setting is appropriate for HDCL1 setting
else if(ClientRequest.HDCL1)
{
EXPECT_GE(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
else
{
EXPECT_LT(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
if(ClientRequest.L3)
{
EXPECT_EQ(L3_WB_CACHEABLE, Mocs.L3.Cacheability) << "Usage# " << Usage << ": Incorrect L3 cachebility setting";
}
else
{
EXPECT_EQ(L3_UNCACHEABLE, Mocs.L3.Cacheability) << "Usage# " << Usage << ": Incorrect L3 cachebility setting";
}
}
}
TEST_F(CTestGen12CachePolicy, TestL3CachePolicy)
{
CheckL3CachePolicy();
}
void CTestGen12CachePolicy::CheckLlcEdramCachePolicy()
{
const uint32_t TargetCache_LLC = 1;
const uint32_t LeCC_UNCACHEABLE = 0x0;
const uint32_t LeCC_WC_UNCACHEABLE = 0x1;
const uint32_t LeCC_WB_CACHEABLE = 0x3;
const uint32_t LeCC_WT_CACHEABLE = 0x2;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
uint32_t AssignedMocsIdx = ClientRequest.MemoryObjectOverride.Gen12.Index;
GMM_CACHE_POLICY_TBL_ELEMENT Mocs = pGmmULTClientContext->GetCachePolicyTlbElement(AssignedMocsIdx);
// Check for unused fields
EXPECT_EQ(0, Mocs.LeCC.AOM) << "Usage# " << Usage << ": AOM is non-zero";
EXPECT_EQ(0, Mocs.LeCC.CoS) << "Usage# " << Usage << ": CoS is non-zero";
EXPECT_EQ(0, Mocs.LeCC.PFM) << "Usage# " << Usage << ": PFM is non-zero";
EXPECT_EQ(0, Mocs.LeCC.SCC) << "Usage# " << Usage << ": SCC is non-zero";
// SCF field might be set for LKF/Gen12+ platforms;
EXPECT_EQ(0, Mocs.LeCC.SCF & !const_cast<SKU_FEATURE_TABLE &>(pGfxAdapterInfo->SkuTable).FtrLLCBypass) << "Usage# " << Usage << ": SCF is non-zero";
EXPECT_EQ(0, Mocs.LeCC.ESC) << "Usage# " << Usage << ": ESC is non-zero";
EXPECT_EQ(0, Mocs.LeCC.Reserved) << "Usage# " << Usage << ": Reserved field is non-zero";
// Check for age
EXPECT_EQ(ClientRequest.AGE, Mocs.LeCC.LRUM) << "Usage# " << Usage << ": Incorrect AGE settings";
// Check for Snoop Setting
EXPECT_EQ(ClientRequest.SSO, Mocs.LeCC.SelfSnoop) << "Usage# " << Usage << ": Self Snoop is non-zero";
// Check if Mocs Index is not greater than GMM_MAX_NUMBER_MOCS_INDEXES
EXPECT_GT(GMM_MAX_NUMBER_MOCS_INDEXES, AssignedMocsIdx) << "Usage# " << Usage << ": MOCS Index greater than MAX allowed (63)";
if(ClientRequest.L3Eviction == 0x2) //63
{
GMM_CACHE_POLICY_ELEMENT MOCS63 = pGmmULTClientContext->GetCachePolicyElement(GMM_RESOURCE_USAGE_L3_EVICTION);
if((GMM_RESOURCE_USAGE_TYPE)Usage == GMM_RESOURCE_USAGE_L3_EVICTION)
{
EXPECT_EQ(AssignedMocsIdx, 63) << "Usage# " << Usage << ": Incorrect Index for L3Eviction type# " << ClientRequest.L3Eviction;
}
else
{
MOCS63.L3 = 1; //Override L3 to test , since Hw forces it to L3-uncached
EXPECT_NE(AssignedMocsIdx, 63) << "Usage# " << Usage << ": Incorrect Index for L3Eviction type# " << ClientRequest.L3Eviction;
EXPECT_EQ(MOCS63.Value, ClientRequest.Value) << "Usage# " << Usage << ": Incorrect usage for L3Eviction type# " << ClientRequest.L3Eviction;
}
}
else if(ClientRequest.L3Eviction == 0x3) //61
{
GMM_CACHE_POLICY_ELEMENT MOCS61 = pGmmULTClientContext->GetCachePolicyElement(GMM_RESOURCE_USAGE_L3_EVICTION_SPECIAL);
EXPECT_EQ(AssignedMocsIdx, 61) << "Usage# " << Usage << ": Incorrect Index for L3Eviction type# " << ClientRequest.L3Eviction;
EXPECT_EQ(0, ClientRequest.LLC) << "Usage# " << Usage << ": Incorrect LLC cacheability for L3Eviction type# " << ClientRequest.L3Eviction;
EXPECT_EQ(MOCS61.Value, ClientRequest.Value) << "Usage# " << Usage << ": Incorrect usage for L3Eviction type# " << ClientRequest.L3Eviction;
}
else if(Usage == GMM_RESOURCE_USAGE_CCS) //60
{
EXPECT_EQ(AssignedMocsIdx, 60) << "Usage# " << Usage << ": Incorrect Index for CCS";
}
else if(Usage == GMM_RESOURCE_USAGE_MOCS_62) //62
{
EXPECT_EQ(AssignedMocsIdx, 62) << "Usage# " << Usage << ": Incorrect Index for MOCS_62";
}
// Check of assigned Index setting is appropriate for HDCL1 setting
else if(ClientRequest.HDCL1)
{
EXPECT_GE(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
else
{
EXPECT_LT(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
if(!ClientRequest.LLC && !ClientRequest.ELLC) // Uncached
{
EXPECT_EQ(LeCC_WC_UNCACHEABLE, Mocs.LeCC.Cacheability) << "Usage# " << Usage << ": Incorrect LLC/eDRAM cachebility setting";
}
else
{
if(ClientRequest.LLC) // LLC only
{
EXPECT_EQ(TargetCache_LLC, Mocs.LeCC.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
EXPECT_EQ(LeCC_WB_CACHEABLE, Mocs.LeCC.Cacheability) << "Usage# " << Usage << ": Incorrect LLC cachebility setting";
}
else
{
EXPECT_EQ(TargetCache_LLC, Mocs.LeCC.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
EXPECT_EQ(LeCC_WC_UNCACHEABLE, Mocs.LeCC.Cacheability) << "Usage# " << Usage << ": Incorrect LLC cachebility setting";
}
}
}
}
TEST_F(CTestGen12CachePolicy, TestLlcEdramCachePolicy)
{
CheckLlcEdramCachePolicy();
}

View File

@ -0,0 +1,37 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmCachePolicyULT.h"
class CTestGen12CachePolicy : public CTestCachePolicy
{
protected:
virtual void CheckL3CachePolicy();
virtual void CheckLlcEdramCachePolicy();
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
#pragma once

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
/*==============================================================================
Copyright(c) 2019 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmGen10ResourceULT.h"
#include "../GmmLib/inc/Internal/Common/Platform/GmmGen12Platform.h"
class CTestGen12Resource : public CTestGen10Resource
{
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
#define DEFINE_TILE(xxx, bpp) \
(bpp == TEST_BPP_8) ? TILE_##xxx##_8bpe : \
(bpp == TEST_BPP_16) ? TILE_##xxx##_16bpe : \
(bpp == TEST_BPP_32) ? TILE_##xxx##_32bpe : \
(bpp == TEST_BPP_64) ? TILE_##xxx##_64bpe : \
TILE_##xxx##_128bpe

View File

@ -0,0 +1,222 @@
/*==============================================================================
Copyright(c) 2020 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmGen12dGPUCachePolicyULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// Sets up common environment for Cache Policy fixture tests. this is called once per
/// test case before executing all tests under resource fixture test case.
/// It also calls SetupTestCase from CommonULT to initialize global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen12dGPUCachePolicy::SetUpTestCase()
{
}
/////////////////////////////////////////////////////////////////////////////////////
/// cleans up once all the tests finish execution. It also calls TearDownTestCase
/// from CommonULT to destroy global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen12dGPUCachePolicy::TearDownTestCase()
{
}
void CTestGen12dGPUCachePolicy::SetUpGen12dGPUVariant(PRODUCT_FAMILY platform)
{
printf("%s\n", __FUNCTION__);
GfxPlatform.eProductFamily = platform;
GfxPlatform.eRenderCoreFamily = IGFX_XE_HPG_CORE;
pGfxAdapterInfo = (ADAPTER_INFO *)malloc(sizeof(ADAPTER_INFO));
if(pGfxAdapterInfo)
{
memset(pGfxAdapterInfo, 0, sizeof(ADAPTER_INFO));
pGfxAdapterInfo->SkuTable.FtrLinearCCS = 1; //legacy y =>0 - test both
pGfxAdapterInfo->SkuTable.FtrStandardMipTailFormat = 1;
pGfxAdapterInfo->SkuTable.FtrTileY = 0;
pGfxAdapterInfo->SkuTable.FtrLocalMemory = 1;
CommonULT::SetUpTestCase();
}
}
void CTestGen12dGPUCachePolicy::TearDownGen12dGPUVariant()
{
printf("%s\n", __FUNCTION__);
CommonULT::TearDownTestCase();
}
TEST_F(CTestGen12dGPUCachePolicy, TestGen12dGPU_DG1CachePolicy)
{
SetUpGen12dGPUVariant(IGFX_DG1);
CheckL3Gen12dGPUCachePolicy();
TearDownGen12dGPUVariant();
}
TEST_F(CTestGen12dGPUCachePolicy, TestGen12dGPU_XE_HP_SDVCachePolicy)
{
SetUpGen12dGPUVariant(IGFX_XE_HP_SDV);
CheckL3Gen12dGPUCachePolicy();
TearDownGen12dGPUVariant();
}
void CTestGen12dGPUCachePolicy::CheckSpecialMocs(uint32_t Usage,
uint32_t AssignedMocsIdx,
GMM_CACHE_POLICY_ELEMENT ClientRequest)
{
if(Usage == GMM_RESOURCE_USAGE_CCS) //60
{
EXPECT_EQ(AssignedMocsIdx, 60) << "Usage# " << Usage << ": Incorrect Index for CCS";
EXPECT_EQ(0, ClientRequest.L3) << "Usage# " << Usage << ": Incorrect L3 cacheability for CCS";
EXPECT_EQ(0, ClientRequest.UcLookup) << "Usage# " << Usage << ": Incorrect L3 LookUp cacheability for CCS";
}
else if(Usage == GMM_RESOURCE_USAGE_CCS_MEDIA_WRITABLE) // 61
{
EXPECT_EQ(AssignedMocsIdx, 61) << "Usage# " << Usage << ": Incorrect Index for CCS";
EXPECT_EQ(0, ClientRequest.L3) << "Usage# " << Usage << ": Incorrect L3 cacheability for CCS";
EXPECT_EQ(0, ClientRequest.UcLookup) << "Usage# " << Usage << ": Incorrect L3 LookUp cacheability for CCS";
}
else if(Usage == GMM_RESOURCE_USAGE_MOCS_62) //62
{
EXPECT_EQ(AssignedMocsIdx, 62) << "Usage# " << Usage << ": Incorrect Index for MOCS_62";
EXPECT_EQ(0, ClientRequest.L3) << "Usage# " << Usage << ": Incorrect L3 cacheability for MOCS#62";
}
}
void CTestGen12dGPUCachePolicy::CheckMocsIdxHDCL1(uint32_t Usage,
uint32_t AssignedMocsIdx,
GMM_CACHE_POLICY_ELEMENT ClientRequest)
{
#define GMM_GEN12_MAX_NUMBER_MOCS_INDEXES (60) // On TGL last four (#60-#63) are reserved by h/w, few? are sw configurable though (#60)
// Check of assigned Index setting is appropriate for HDCL1 setting
if(ClientRequest.HDCL1)
{
EXPECT_GE(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Index must be greater than " << GMM_GEN10_HDCL1_MOCS_INDEX_START - 1 << " for HDCL1 setting. AssignedMocs: " << AssignedMocsIdx;
EXPECT_LT(AssignedMocsIdx, GMM_GEN12_MAX_NUMBER_MOCS_INDEXES) << "Usage# " << Usage << ": Index must be less than " << GMM_GEN12_MAX_NUMBER_MOCS_INDEXES << "for HDCL1 setting";
}
else if(AssignedMocsIdx < GMM_GEN12_MAX_NUMBER_MOCS_INDEXES)
{
EXPECT_LT(AssignedMocsIdx, GMM_GEN10_HDCL1_MOCS_INDEX_START) << "Usage# " << Usage << ": Incorrect Index for HDCL1 setting";
}
}
void CTestGen12dGPUCachePolicy::CheckL3Gen12dGPUCachePolicy()
{
const uint32_t L3_WB_CACHEABLE = 0x3;
const uint32_t L3_UNCACHEABLE = 0x1;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
uint32_t AssignedMocsIdx = ClientRequest.MemoryObjectOverride.Gen12.Index;
GMM_CACHE_POLICY_TBL_ELEMENT Mocs = pGmmULTClientContext->GetCachePolicyTlbElement(AssignedMocsIdx);
uint32_t StartMocsIdx = 1;
//printf("Usage: %d --> Index: [%d]\n", Usage, AssignedMocsIdx);
if(GfxPlatform.eProductFamily == IGFX_DG2)
{
StartMocsIdx = 0;
}
if(StartMocsIdx == 1)
{
EXPECT_NE(0, AssignedMocsIdx) << "Usage# " << Usage << ": Misprogramming MOCS - Index 0 is reserved for Error";
}
EXPECT_EQ(0, Mocs.L3.ESC) << "Usage# " << Usage << ": ESC is non-zero";
EXPECT_EQ(0, Mocs.L3.SCC) << "Usage# " << Usage << ": SCC is non-zero";
EXPECT_EQ(0, Mocs.L3.Reserved) << "Usage# " << Usage << ": Reserved field is non-zero";
// Check if Mocs Index is not greater than GMM_MAX_NUMBER_MOCS_INDEXES
EXPECT_GT(GMM_MAX_NUMBER_MOCS_INDEXES, AssignedMocsIdx) << "Usage# " << Usage << ": MOCS Index greater than MAX allowed (63)";
if(GfxPlatform.eProductFamily <= IGFX_XE_HP_SDV)
{
CheckMocsIdxHDCL1(Usage, AssignedMocsIdx, ClientRequest);
}
if(GfxPlatform.eProductFamily < IGFX_DG2)
{
CheckSpecialMocs(Usage, AssignedMocsIdx, ClientRequest);
}
if(ClientRequest.L3)
{
EXPECT_EQ(L3_WB_CACHEABLE, Mocs.L3.Cacheability) << "Usage# " << Usage << ": Incorrect L3 cachebility setting";
}
else
{
EXPECT_EQ(L3_UNCACHEABLE, Mocs.L3.Cacheability) << "Usage# " << Usage << ": Incorrect L3 cachebility setting";
}
}
}
void CTestXe_HP_CachePolicy::SetUpPlatformVariant(PRODUCT_FAMILY platform)
{
printf("%s\n", __FUNCTION__);
CTestGen12dGPUCachePolicy::SetUpGen12dGPUVariant(platform);
}
void CTestXe_HP_CachePolicy::TearDownPlatformVariant()
{
printf("%s\n", __FUNCTION__);
CTestGen12dGPUCachePolicy::TearDownGen12dGPUVariant();
}
void CTestXe_HP_CachePolicy::CheckL3CachePolicy()
{
printf("%s\n", __FUNCTION__);
CTestGen12dGPUCachePolicy::CheckL3Gen12dGPUCachePolicy();
}
void CTestXe_HP_CachePolicy::SetUpTestCase()
{
}
void CTestXe_HP_CachePolicy::TearDownTestCase()
{
}
TEST_F(CTestXe_HP_CachePolicy, Test_DG2_CachePolicy)
{
SetUpPlatformVariant(IGFX_DG2);
CheckL3CachePolicy();
TearDownPlatformVariant();
}
TEST_F(CTestXe_HP_CachePolicy, Test_PVC_CachePolicy)
{
SetUpPlatformVariant(IGFX_PVC);
CheckL3CachePolicy();
TearDownPlatformVariant();
}

View File

@ -0,0 +1,57 @@
/*==============================================================================
Copyright(c) 2020 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmCachePolicyULT.h"
class CTestGen12dGPUCachePolicy : public CTestCachePolicy
{
protected:
virtual void SetUpGen12dGPUVariant(PRODUCT_FAMILY);
virtual void TearDownGen12dGPUVariant();
virtual void CheckL3Gen12dGPUCachePolicy();
virtual void CheckSpecialMocs(uint32_t Usage,
uint32_t AssignedMocsIdx,
GMM_CACHE_POLICY_ELEMENT ClientRequest);
virtual void CheckMocsIdxHDCL1(uint32_t Usage,
uint32_t AssignedMocsIdx,
GMM_CACHE_POLICY_ELEMENT ClientRequest);
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
class CTestXe_HP_CachePolicy : public CTestGen12dGPUCachePolicy
{
protected:
virtual void SetUpPlatformVariant(PRODUCT_FAMILY);
virtual void TearDownPlatformVariant();
virtual void CheckL3CachePolicy();
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
#pragma once

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
/*==============================================================================
Copyright(c) 2020 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmGen10ResourceULT.h"
#include "../GmmLib/inc/Internal/Common/Platform/GmmGen12Platform.h"
class CTestGen12dGPUResource : public CTestGen10Resource
{
public:
static void SetUpTestCase();
static void TearDownTestCase();
};
#define DEFINE_TILE(xxx, bpp) \
(bpp == TEST_BPP_8) ? TILE_##xxx##_8bpe : \
(bpp == TEST_BPP_16) ? TILE_##xxx##_16bpe : \
(bpp == TEST_BPP_32) ? TILE_##xxx##_32bpe : \
(bpp == TEST_BPP_64) ? TILE_##xxx##_64bpe : \
TILE_##xxx##_128bpe

View File

@ -0,0 +1,152 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmGen9CachePolicyULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// Sets up common environment for Cache Policy fixture tests. this is called once per
/// test case before executing all tests under resource fixture test case.
/// It also calls SetupTestCase from CommonULT to initialize global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen9CachePolicy::SetUpTestCase()
{
GfxPlatform.eProductFamily = IGFX_SKYLAKE;
GfxPlatform.eRenderCoreFamily = IGFX_GEN9_CORE;
AllocateAdapterInfo();
pGfxAdapterInfo->SystemInfo.L3CacheSizeInKb = 768;
pGfxAdapterInfo->SystemInfo.LLCCacheSizeInKb = 2 * 1024; //2 MB
pGfxAdapterInfo->SystemInfo.EdramSizeInKb = 128 * 1024; //128 MB
const_cast<SKU_FEATURE_TABLE &>(pGfxAdapterInfo->SkuTable).FtrEDram = 1;
CommonULT::SetUpTestCase();
printf("%s\n", __FUNCTION__);
}
/////////////////////////////////////////////////////////////////////////////////////
/// cleans up once all the tests finish execution. It also calls TearDownTestCase
/// from CommonULT to destroy global context and others.
///
/////////////////////////////////////////////////////////////////////////////////////
void CTestGen9CachePolicy::TearDownTestCase()
{
printf("%s\n", __FUNCTION__);
CommonULT::TearDownTestCase();
}
void CTestGen9CachePolicy::CheckL3CachePolicy()
{
const uint32_t L3_WB_CACHEABLE = 0x3;
const uint32_t L3_UNCACHEABLE = 0x1;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
uint32_t AssignedMocsIdx = ClientRequest.MemoryObjectOverride.Gen9.Index;
GMM_CACHE_POLICY_TBL_ELEMENT Mocs = pGmmULTClientContext->GetCachePolicyTlbElement(AssignedMocsIdx);
EXPECT_EQ(0, Mocs.L3.ESC) << "Usage# " << Usage << ": ESC is non-zero";
EXPECT_EQ(0, Mocs.L3.SCC) << "Usage# " << Usage << ": SCC is non-zero";
EXPECT_EQ(0, Mocs.L3.Reserved) << "Usage# " << Usage << ": Reserved field is non-zero";
if(ClientRequest.L3)
{
EXPECT_EQ(L3_WB_CACHEABLE, Mocs.L3.Cacheability) << "Usage# " << Usage << ": Incorrect L3 cachebility setting";
}
else
{
EXPECT_EQ(L3_UNCACHEABLE, Mocs.L3.Cacheability) << "Usage# " << Usage << ": Incorrect L3 cachebility setting";
}
}
}
TEST_F(CTestGen9CachePolicy, TestL3CachePolicy)
{
CheckL3CachePolicy();
}
void CTestGen9CachePolicy::CheckLlcEdramCachePolicy()
{
const uint32_t TargetCache_ELLC = 0;
const uint32_t TargetCache_LLC = 1;
const uint32_t TargetCache_LLC_ELLC = 2;
const uint32_t LeCC_UNCACHEABLE = 0x1;
const uint32_t LeCC_WB_CACHEABLE = 0x3;
// Check Usage MOCS index against MOCS settings
for(uint32_t Usage = GMM_RESOURCE_USAGE_UNKNOWN; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
{
GMM_CACHE_POLICY_ELEMENT ClientRequest = pGmmULTClientContext->GetCachePolicyElement((GMM_RESOURCE_USAGE_TYPE)Usage);
uint32_t AssignedMocsIdx = ClientRequest.MemoryObjectOverride.Gen9.Index;
GMM_CACHE_POLICY_TBL_ELEMENT Mocs = pGmmULTClientContext->GetCachePolicyTlbElement(AssignedMocsIdx);
// Check for unused fields
EXPECT_EQ(0, Mocs.LeCC.AOM) << "Usage# " << Usage << ": AOM is non-zero";
EXPECT_EQ(0, Mocs.LeCC.CoS) << "Usage# " << Usage << ": CoS is non-zero";
EXPECT_EQ(0, Mocs.LeCC.PFM) << "Usage# " << Usage << ": PFM is non-zero";
EXPECT_EQ(0, Mocs.LeCC.SCC) << "Usage# " << Usage << ": SCC is non-zero";
EXPECT_EQ(0, Mocs.LeCC.SCF) << "Usage# " << Usage << ": SCF is non-zero";
EXPECT_EQ(0, Mocs.LeCC.SelfSnoop) << "Usage# " << Usage << ": Self Snoop is non-zero";
EXPECT_EQ(0, Mocs.LeCC.ESC) << "Usage# " << Usage << ": ESC is non-zero";
EXPECT_EQ(0, Mocs.LeCC.Reserved) << "Usage# " << Usage << ": Reserved field is non-zero";
// Check for age
EXPECT_EQ(ClientRequest.AGE, Mocs.LeCC.LRUM) << "Usage# " << Usage << ": Incorrect AGE settings";
if(!ClientRequest.LLC && !ClientRequest.ELLC) // Uncached
{
EXPECT_EQ(LeCC_UNCACHEABLE, Mocs.LeCC.Cacheability) << "Usage# " << Usage << ": Incorrect LLC/eDRAM cachebility setting";
}
else
{
EXPECT_EQ(LeCC_WB_CACHEABLE, Mocs.LeCC.Cacheability) << "Usage# " << Usage << ": Incorrect LLC/eDRAM cachebility setting";
if(ClientRequest.LLC && !ClientRequest.ELLC) // LLC only
{
EXPECT_EQ(TargetCache_LLC, Mocs.LeCC.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
}
else if(!ClientRequest.LLC && ClientRequest.ELLC) // eLLC only
{
EXPECT_EQ(TargetCache_ELLC, Mocs.LeCC.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
}
else
{
EXPECT_EQ(TargetCache_LLC_ELLC, Mocs.LeCC.TargetCache) << "Usage# " << Usage << ": Incorrect target cache setting";
}
}
}
}
TEST_F(CTestGen9CachePolicy, TestLlcEdramCachePolicy)
{
CheckLlcEdramCachePolicy();
}

View File

@ -0,0 +1,37 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmCachePolicyULT.h"
class CTestGen9CachePolicy : public CTestCachePolicy
{
protected:
virtual void CheckL3CachePolicy();
virtual void CheckLlcEdramCachePolicy();
public:
static void SetUpTestCase();
static void TearDownTestCase();
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,131 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmResourceULT.h"
class CTestGen9Resource : public CTestResource
{
protected:
void FillExpectedPitch();
void FillExpectedPitchInTiles();
void FillExpectedHAlign();
void FillExpectedVAlign();
void FillExpectedDAlign();
void FillExpectedSize();
void FillExpectedQPitch();
void FillExpectedMipOffsets();
public:
static void SetUpTestCase();
static void TearDownTestCase();
/////////////////////////////////////////////////////////////////////////////////////
/// Get the Tile dimension and RT->CCS downscale factor
///
/// @param[in] Bpp: bits per pixel
/// @param[in] Tiling: Tile Type
/// @param[in] ResType: Resource Type
/// @param[out] TileDimX: Tile Width for given Tile, Resource, bpp
/// @param[out] TileDimY: Tile Height for given Tile, Resource, bpp
/// @param[out] TileDimZ: Tile Depth for given Tile, Resource, bpp
/// @param[out] WidthDivisor: RT->CCS width downscale factor
/// @param[out] HeightDivisor: RT->CCS height downscale factor
///
/////////////////////////////////////////////////////////////////////////////////////
void GetAlignmentAndTileDimensionsForCCS(TEST_BPP Bpp, TEST_TILE_TYPE Tiling, TEST_RESOURCE_TYPE ResType,
uint32_t &TileDimX, uint32_t &TileDimY, uint32_t & TileDimZ,
uint32_t &WidthDivisor, uint32_t &HeightDivisor)
{
const uint32_t RT2DTileSize[TEST_TILE_MAX][TEST_BPP_MAX][3] = {
{ { 64, 1, 1 },{ 64, 1, 1 },{ 64, 1, 1 },{ 64, 1, 1 },{ 64, 1, 1 } }, //Linear - no Tile Size, but min PitchAlign = 64 (cacheLine size)
{ { 512, 8, 1 },{ 512, 8,1 },{ 512, 8,1 },{ 512, 8, 1 },{ 512, 8, 1 } }, //TileX
{ { 128, 32, 1 },{ 128, 32, 1 },{ 128, 32, 1 },{ 128, 32, 1 },{ 128, 32, 1 } }, //TileY
{ { 256, 256, 1 },{ 512, 128, 1 },{ 512, 128, 1 },{ 1024, 64, 1 },{ 1024, 64, 1 } }, //TileYs
{ { 64, 64, 1 },{ 128, 32, 1 },{ 128, 32,1 },{ 256, 16, 1 },{ 256, 16, 1 } } //TileYf
};
const uint32_t RT3DTileSize[TEST_TILE_MAX][TEST_BPP_MAX][3] = {
{ { 64, 1, 1 },{ 64, 1, 1 },{ 64, 1, 1 },{ 64, 1, 1 },{ 64, 1, 1 } }, //Linear - no Tile Size, but min PitchAlign = 64 (cacheLine size)
{ { 512, 8, 1 },{ 512, 8, 1 },{ 512, 8, 1 },{ 512, 8, 1 },{ 512, 8, 1 } }, //TileX
{ { 128, 32, 1 },{ 128, 32, 1 },{ 128, 32, 1 },{ 128, 32, 1 },{ 128, 32, 1 } }, //TileY
{ { 64, 32, 32 },{ 64, 32, 32 },{ 128, 32, 16 },{ 256, 16, 16 },{ 512, 16, 16 } }, //TileYs
{ { 16, 16, 16 },{ 16, 16, 16 },{ 32, 16, 8 },{ 64, 8, 8 },{ 64, 8, 8 } } //TileYf
};
uint32_t TileDim[3] = { RT2DTileSize[Tiling][Bpp][0], RT2DTileSize[Tiling][Bpp][1], RT2DTileSize[Tiling][Bpp][2] };
if (ResType == TEST_RESOURCE_3D)
{
TileDim[0] = RT3DTileSize[Tiling][Bpp][0];
TileDim[1] = RT3DTileSize[Tiling][Bpp][1];
TileDim[2] = RT3DTileSize[Tiling][Bpp][2];
}
TileDimX = TileDim[0];
TileDimY = TileDim[1];
TileDimZ = TileDim[2];
uint32_t ExpectedCCSBpp = 1; //1 byte per pixel (contains 4 2b-CCS,
//Each 2b covers 2CLs = 128B RT)
/***
2b-CCS per 2CLs of RT (2:1 compression ie 2CL->1CL)
1B-CCS covers 4x2 RT CLs (as square as possible in px)
CL Byte size 16 x 4
8CLs could cover {(16x32), (128x4), (64x8), (32x16)} Byte-blocks, of which last one is most-square hence should be used
ie RT coverage by 1B CCS is 32x16, taking RT-bpp into account:
bpp RT-coverage in pixel by 1B CCS
32 32/4 x 16 = 8x16
64 32/8 x 16 = 4x16
128 32/16 x 16 = 2x16
Finally CCS needs to be Tile-aligned (TileY)
***/
const uint32_t RTWidthDivisor[2][TEST_BPP_MAX] = { { 1, 1, 16, 8, 4 },{ 1, 1, 8, 4, 2 } }; //Divisor for TileX, TileY
const uint32_t RTHeightDivisor[2] = { 8, 16 };
uint32_t Idx = (Tiling == TEST_TILEX) ? 0 : 1;
WidthDivisor = RTWidthDivisor[Idx][Bpp];
HeightDivisor = RTHeightDivisor[Idx];
}
/////////////////////////////////////////////////////////////////////////////////////
/// Verifies if Mip tail start Lod matches the expected value. Fails test if value
/// doesn't match
///
/// @param[in] ResourceInfo: ResourceInfo returned by GmmLib
/// @param[in] ExpectedValue: expected value to check against
/////////////////////////////////////////////////////////////////////////////////////
template <bool Verify>
void VerifyResourceMipTailStartLod(GMM_RESOURCE_INFO *ResourceInfo, uint32_t ExpectedValue)
{
if (Verify)
{
EXPECT_EQ(ExpectedValue, ResourceInfo->GetMipTailStartLodSurfaceState());
}
}
CTestGen9Resource();
~CTestGen9Resource();
};

View File

@ -0,0 +1,531 @@
/*========================== begin_copyright_notice ============================
Copyright(c) 2021 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================= end_copyright_notice ===========================*/
#include "GmmMultiAdapterULT.h"
#ifndef _WIN32
#include <dlfcn.h>
#endif
#include <stdlib.h>
ADAPTER_INFO * MACommonULT::pGfxAdapterInfo[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
PLATFORM MACommonULT::GfxPlatform[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
GMM_LIB_CONTEXT * MACommonULT::pLibContext[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
GMM_CLIENT_CONTEXT *MACommonULT::pGmmULTClientContext[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
PFNGMMINIT MACommonULT::pfnGmmInit[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
PFNGMMDESTROY MACommonULT::pfnGmmDestroy[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
GMM_INIT_IN_ARGS MACommonULT::InArgs[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
GMM_INIT_OUT_ARGS MACommonULT::OutArgs[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
GMM_DLL_HANDLE MACommonULT::hGmmLib[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
// Comman array for all thread related ULTs to supply Adapter-Client Context input.
ThreadInParams MACommonULT::InParams[MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER];
// Array to store the adapter BDFs from simulated UMD, Save the adapter bdf in an array.
ADAPTER_BDF MACommonULT::AdpaterSaved[MAX_NUM_ADAPTERS];
MACommonULT::MACommonULT()
{
}
MACommonULT::~MACommonULT()
{
}
void MACommonULT::SetUpTestCase()
{
}
void MACommonULT::TearDownTestCase()
{
}
CTestMA::CTestMA()
{
uint32_t i = 0;
memset(AdpaterSaved, 0, sizeof(AdpaterSaved));
// Save the random Generated bdf value in an array during intantiation itself
// These value remain live for each of the ULT lifetime.
for(i = 0; i < MAX_NUM_ADAPTERS; i++)
{
AdpaterSaved[i].Bus = rand() / 100;
AdpaterSaved[i].Device = rand() / 100;
AdpaterSaved[i].Function = rand() / 100;
AdpaterSaved[i].Reserved = 0;
}
// Validate the generated BDfs are unique
// No two Adapter's BDF should be equal on a PCI bus.
for(i = 0; i < MAX_NUM_ADAPTERS; i++)
{
for(uint32_t j = 0; j < MAX_NUM_ADAPTERS; j++)
{
if(i != j)
{
if(AdpaterSaved[i].Bus == AdpaterSaved[j].Bus)
{
if(AdpaterSaved[i].Device == AdpaterSaved[j].Device)
{
if(AdpaterSaved[i].Function == AdpaterSaved[j].Function)
{
// OOps! Generated BDFs are equal.
// Lets change any one field to make it unique
// Lets increment Bus.
AdpaterSaved[j].Bus++;
}
}
}
}
}
}
}
CTestMA::~CTestMA()
{
}
void CTestMA::SetUpTestCase()
{
}
void CTestMA::TearDownTestCase()
{
}
void MACommonULT::LoadGmmDll(uint32_t AdapterIdx, uint32_t CountIdx)
{
hGmmLib[AdapterIdx][CountIdx] = dlopen(GMM_UMD_DLL, RTLD_LAZY);
ASSERT_TRUE(hGmmLib[AdapterIdx][CountIdx]);
*(void **)(&pfnGmmInit[AdapterIdx][CountIdx]) = dlsym(hGmmLib[AdapterIdx][CountIdx], "InitializeGmm");
*(void **)(&pfnGmmDestroy[AdapterIdx][CountIdx]) = dlsym(hGmmLib[AdapterIdx][CountIdx], "GmmAdapterDestroy");
ASSERT_TRUE(pfnGmmInit[AdapterIdx][CountIdx]);
ASSERT_TRUE(pfnGmmDestroy[AdapterIdx][CountIdx]);
}
void MACommonULT::UnLoadGmmDll(uint32_t AdapterIdx, uint32_t CountIdx)
{
if(hGmmLib[AdapterIdx][CountIdx])
{
dlclose(hGmmLib[AdapterIdx][CountIdx]);
hGmmLib[AdapterIdx][CountIdx] = NULL;
}
}
void MACommonULT::GmmInitModule(uint32_t AdapterIdx, uint32_t CountIdx)
{
GMM_STATUS Status = GMM_SUCCESS;
ADAPTER_BDF AdapterBDF = GetAdapterBDF(AdapterIdx);
GfxPlatform[AdapterIdx][CountIdx].eProductFamily = GetProductFamily(AdapterIdx);
GfxPlatform[AdapterIdx][CountIdx].eRenderCoreFamily = GetRenderCoreFamily(AdapterIdx);
if(!pGfxAdapterInfo[AdapterIdx][CountIdx])
{
pGfxAdapterInfo[AdapterIdx][CountIdx] = (ADAPTER_INFO *)malloc(sizeof(ADAPTER_INFO));
if(!pGfxAdapterInfo[AdapterIdx][CountIdx])
{
ASSERT_TRUE(false);
return;
}
memset(pGfxAdapterInfo[AdapterIdx][CountIdx], 0, sizeof(ADAPTER_INFO));
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrTileY = 1; // Legacy TileY
if(GfxPlatform[AdapterIdx][CountIdx].eRenderCoreFamily >= IGFX_GEN12_CORE)
{
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrWddm2GpuMmu = 1;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrUserModeTranslationTable = 1;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrE2ECompression = 1;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrLinearCCS = 1;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrTileY = 1;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrLLCBypass = 0;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrWddm2Svm = 0;
}
if(IGFX_DG1 == GfxPlatform[AdapterIdx][CountIdx].eProductFamily)
{
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrLinearCCS = 1;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrStandardMipTailFormat = 1;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrTileY = 0;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrLocalMemory = 1;
pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable.FtrWddm2_1_64kbPages = 1;
}
}
InArgs[AdapterIdx][CountIdx].ClientType = GetClientType(CountIdx);
InArgs[AdapterIdx][CountIdx].pGtSysInfo = &pGfxAdapterInfo[AdapterIdx][CountIdx]->SystemInfo;
InArgs[AdapterIdx][CountIdx].pSkuTable = &pGfxAdapterInfo[AdapterIdx][CountIdx]->SkuTable;
InArgs[AdapterIdx][CountIdx].pWaTable = &pGfxAdapterInfo[AdapterIdx][CountIdx]->WaTable;
InArgs[AdapterIdx][CountIdx].Platform = GfxPlatform[AdapterIdx][CountIdx];
#if LHDM
InArgs[AdapterIdx][CountIdx].stAdapterBDF = AdapterBDF;
InArgs[AdapterIdx][CountIdx].DeviceRegistryPath = NULL;
#else
InArgs[AdapterIdx][CountIdx].FileDescriptor = AdapterBDF.Data;
#endif
Status = pfnGmmInit[AdapterIdx][CountIdx](&InArgs[AdapterIdx][CountIdx], &OutArgs[AdapterIdx][CountIdx]);
EXPECT_EQ(Status, GMM_SUCCESS);
pGmmULTClientContext[AdapterIdx][CountIdx] = OutArgs[AdapterIdx][CountIdx].pGmmClientContext;
ASSERT_TRUE(pGmmULTClientContext[AdapterIdx][CountIdx]);
pLibContext[AdapterIdx][CountIdx] = pGmmULTClientContext[AdapterIdx][CountIdx]->GetLibContext();
ASSERT_TRUE(pLibContext[AdapterIdx][CountIdx]);
}
void MACommonULT::GmmDestroyModule(uint32_t AdapterIdx, uint32_t CountIdx)
{
OutArgs[AdapterIdx][CountIdx].pGmmClientContext = pGmmULTClientContext[AdapterIdx][CountIdx];
pfnGmmDestroy[AdapterIdx][CountIdx](&OutArgs[AdapterIdx][CountIdx]);
pGmmULTClientContext[AdapterIdx][CountIdx] = NULL;
pLibContext[AdapterIdx][CountIdx] = NULL;
if(pGfxAdapterInfo[AdapterIdx][CountIdx])
{
free(pGfxAdapterInfo[AdapterIdx][CountIdx]);
pGfxAdapterInfo[AdapterIdx][CountIdx] = NULL;
}
}
// This member function creates MaxClientThreads number of threads
// MaxClientsThreads to represent total numbers of UMD Clients
// MaxClientsThreads = MAX_NUM_ADAPTERS for ULT TestMTLoadMultipleAdapters
// MaxClientsThreads = MAX_COUNT_PER_ADAPTER for ULT TestMTLoadAdaptersMultipleTimes
// MaxClientsThreads = MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER, for ULT TestMTLoadMultipleAdaptersMultipleTimes
void MACommonULT::CreateMAThread(uint32_t MaxClientThreads)
{
// Spawn all threads upto MaxClientThreads and wait for them all at once
uint32_t i = 0;
int Status; /* return value */
pthread_t thread_id[MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER]; /* thread's ID (just an integer) */
/* MaxClientsThreads to represent MAX_NUM_ADAPTERS *MAX_COUNT_PER_ADAPTER Clients */
for(i = 0; i < (MaxClientThreads); i++)
{
Status = pthread_create(&thread_id[i], NULL, Thread1, (void *)&InParams[i]);
ASSERT_TRUE((!Status));
}
/* wait for threads to terminate */
for(i = 0; i < (MaxClientThreads); i++)
{
Status = pthread_join(thread_id[i], NULL);
ASSERT_TRUE((!Status));
}
}
void *Thread1(void *lpParam)
{
ThreadInParams *pInParams = (ThreadInParams *)(lpParam);
MACommonULT::LoadGmmDll(pInParams->AdapterIdx, pInParams->CountIdx);
MACommonULT::GmmInitModule(pInParams->AdapterIdx, pInParams->CountIdx);
MACommonULT::GmmDestroyModule(pInParams->AdapterIdx, pInParams->CountIdx);
MACommonULT::UnLoadGmmDll(pInParams->AdapterIdx, pInParams->CountIdx);
pthread_exit(NULL);
}
#if GMM_LIB_DLL_MA
/*
To simulate the real time scenario between the Gmmlib and the UMD clients
Folowing ULTs assume:
MAX_NUM_ADAPTERS = Number of GPU Adapters (BDFs) available on a system at a given point of time.
MAX_COUNT_PER_ADAPTER = Number of UMD clients that can be simulated per Adapter
So Total clients simulated = MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER
Where,
The LibContext for an Adapter is equal across all Clients for that adapter
The ClientConetxt is unique(Not equal) across all Clients for that adapter
*/
// Load multiple Adapters in the same process with the Limit up to MAX_NUM_ADAPTERS
// Increase MAX_NUM_ADAPTERS > 32 if needed
TEST_F(CTestMA, TestLoadMultipleAdapters)
{
uint32_t AdapterCount = 0;
uint32_t i = 0;
// Load the dll for all available adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
LoadGmmDll(AdapterCount, 0);
}
// Initilize the dll for all available adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
GmmInitModule(AdapterCount, 0);
}
// Check the Libcontext for each of the adapter is different or not
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(i = 0; i < MAX_NUM_ADAPTERS; i++)
{
if(AdapterCount != i)
{
EXPECT_NE(pLibContext[AdapterCount][0], pLibContext[i][0]);
}
}
}
// Un-Initilize the dll for all loaded adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
GmmDestroyModule(AdapterCount, 0);
}
// Unload the dll for all loaded adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
UnLoadGmmDll(AdapterCount, 0);
}
}
/// Load all adapters(MAX_NUM_ADAPTERS) multiple times up to MAX_COUNT_PER_ADAPTER in same process
TEST_F(CTestMA, TestLoadAdapterMultipleTimes)
{
uint32_t AdapterCount = 0, RefCount = 0;
// Load the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
LoadGmmDll(AdapterCount, RefCount);
}
}
// Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
GmmInitModule(AdapterCount, RefCount);
}
}
// For each adapter upto MAX_NUM_ADAPTERS Check the LibContext for all instances upto
// MAX_COUNT_PER_ADAPTER to be equal
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER - 1; RefCount++)
{
EXPECT_EQ(pLibContext[AdapterCount][RefCount], pLibContext[AdapterCount][RefCount + 1]);
}
}
// Un-Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
// The destroy/unload can be out of order
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
GmmDestroyModule(AdapterCount, RefCount);
}
}
// Unload the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
UnLoadGmmDll(AdapterCount, RefCount);
}
}
}
/// Test Init-Destroy multiple times Upto MAX_COUNT_PER_ADAPTER before Unloading DLL, on Same Adapter upto MAX_NUM_ADAPTERS
TEST_F(CTestMA, TestInitDestroyMultipleTimesOnSameAdapter)
{
uint32_t AdapterCount = 0, RefCount = 0;
// Load the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
LoadGmmDll(AdapterCount, RefCount);
}
}
// Initilize and destroy module upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
// For each adapter(AdapterCount < MAX_NUM_ADAPTERS) Check the LibContext for all instances to be equal
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
// Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each adapter
// In reality the init and destroy can occurs any number of time on a particular adapter, so for simplcity treating that UMD
// will load already loaded lib again for MAX_COUNT_PER_ADAPTER times.
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
GmmInitModule(AdapterCount, RefCount);
}
// Check the LibContext for all instances on a same adapter to be equal
// It might also seems that LibContext pointer value on next adapters is same as previous pointer value returned in previous adapter init.
// This is the OS Memory Manager's role to avoid fragmentation in the process VA space
// Also our ULT is a Light-Weight process due to which the freed memory not assigned to other processes may get assigned again.
// But mind that this is possible only when the previous libcontext intialized is compulsorily inactive and destroyed.
// otherwise the same secnario as in TestLoadMultipleAdapters occurs .i.e different pointer value is returned on new adpater bdf.
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER - 1; RefCount++)
{
EXPECT_EQ(pLibContext[AdapterCount][RefCount], pLibContext[AdapterCount][RefCount + 1]);
}
// Un-Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each adapter
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
GmmDestroyModule(AdapterCount, RefCount);
}
}
// Unload the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
UnLoadGmmDll(AdapterCount, RefCount);
}
}
}
/// Test Init-Destroy multiple times before Unloading DLL, on Multiple Adapters
TEST_F(CTestMA, TestInitDestroyMultipleTimesOnMultiAdapter)
{
uint32_t AdapterCount = 0, RefCount = 0;
// Load the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
LoadGmmDll(AdapterCount, RefCount);
}
}
// Initilize and destroy the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
// For each adapter(AdapterCount < MAX_NUM_ADAPTERS) Check the LibContext for all instances to is unique
// This is similar to TestInitDestroyMultipleTimesOnSameAdapter ULT apart from the order of adapter initialization.
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
// Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each adapter
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
GmmInitModule(AdapterCount, RefCount);
}
// Check the LibContext for each of the adpater(upto MAX_NUM_ADAPTERS) to be unique
// whereas LibContext for all instances on a same adapter is to be equal
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS - 1; AdapterCount++)
{
EXPECT_NE(pLibContext[AdapterCount][RefCount], pLibContext[AdapterCount + 1][RefCount]);
}
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
GmmDestroyModule(AdapterCount, RefCount);
}
}
// Unload the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
UnLoadGmmDll(AdapterCount, RefCount);
}
}
}
/*
Following ULT's Exhibit the multitasking behaviour of UMDs considering that all UMDs loads and unloads dll
in parallel and in random order.
*/
// Load Multiple Adapters upto MAX_NUM_ADAPTERS on multiple threads in same process at the same time
// Here the number of client per adapter is 1 .i.e 0th count Index
TEST_F(CTestMA, TestMTLoadMultipleAdapters)
{
uint32_t AdapterCount = 0;
memset(InParams, 0, sizeof(InParams));
//Populate the Inparams array with the MAX_NUM_ADAPTERS indices
for(AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
{
InParams[AdapterCount].AdapterIdx = AdapterCount;
InParams[AdapterCount].CountIdx = 0;
}
// Create threads to load all Adapters upto MAX_NUM_ADAPTERS for a single client each
CreateMAThread(MAX_NUM_ADAPTERS);
}
// Load a Single Adapter multiple times upto MAX_COUNT_PER_ADAPTER on multiple threads in same process
TEST_F(CTestMA, TestMTLoadAdaptersMultipleTimes)
{
uint32_t RefCount = 0;
memset(InParams, 0, sizeof(InParams));
//Populate the Inparams array with MAX_COUNT_PER_ADAPTER indices
for(RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
{
InParams[RefCount].AdapterIdx = 0;
InParams[RefCount].CountIdx = RefCount;
}
// Create threads to load all clients i.e MAX_COUNT_PER_ADAPTER on single adpater
CreateMAThread(MAX_COUNT_PER_ADAPTER);
}
// Load Multiple Adapters upto MAX_NUM_ADAPTERS, multiple times upto MAX_COUNT_PER_ADAPTER on multiple threads in same process
TEST_F(CTestMA, TestMTLoadMultipleAdaptersMultipleTimes)
{
uint32_t i = 0, j = 0, k = 0;
uint32_t AdapterCount = 0, RefCount = 0;
memset(InParams, 0, sizeof(InParams));
//Populate the Inparams array with the MAX_NUM_ADAPTERS*MAX_COUNT_PER_ADAPTER indices
//Such that Each Adapter corresponds to its max mumber of clients in a sequential order
for(i = 0; i < (MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER); i++)
{
for(j = 0; j < MAX_NUM_ADAPTERS; j++)
{
for(k = 0; k < MAX_COUNT_PER_ADAPTER; k++)
{
InParams[i].AdapterIdx = AdapterCount;
InParams[i].CountIdx = RefCount++;
i++;
}
RefCount = 0;
AdapterCount++;
}
}
// Create threads to load MAX_NUM_ADAPTERS, MAX_COUNT_PER_ADAPTER times
// Thread Count = MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER
CreateMAThread(MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER);
}
#endif // GMM_LIB_DLL_MA

View File

@ -0,0 +1,203 @@
/*========================== begin_copyright_notice ============================
Copyright(c) 2021 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================= end_copyright_notice ===========================*/
#pragma once
#include "stdafx.h"
#include "GmmCommonULT.h"
#define MAX_COUNT_PER_ADAPTER 3
#ifdef _WIN32
#define GMM_DLL_HANDLE HINSTANCE
#else
#define GMM_DLL_HANDLE void*
#endif
typedef struct ThreadInParams_Rec
{
uint32_t AdapterIdx;
uint32_t CountIdx;
} ThreadInParams;
class MACommonULT : public testing::Test
{
public:
MACommonULT();
~MACommonULT();
static void SetUpTestCase();
static void TearDownTestCase();
static void LoadGmmDll(uint32_t AdapterIdx, uint32_t CountIdx);
static void UnLoadGmmDll(uint32_t AdapterIdx, uint32_t CountIdx);
static void GmmInitModule(uint32_t AdapterIdx, uint32_t CountIdx);
static void GmmDestroyModule(uint32_t AdapterIdx, uint32_t CountIdx);
static void CreateMAThread(uint32_t MaxClientThreads);
static ADAPTER_INFO * pGfxAdapterInfo[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
static PLATFORM GfxPlatform[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
static GMM_LIB_CONTEXT * pLibContext[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
static GMM_CLIENT_CONTEXT * pGmmULTClientContext[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
static PFNGMMINIT pfnGmmInit[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
static PFNGMMDESTROY pfnGmmDestroy[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
static GMM_INIT_IN_ARGS InArgs[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
static GMM_INIT_OUT_ARGS OutArgs[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
static GMM_DLL_HANDLE hGmmLib[MAX_NUM_ADAPTERS][MAX_COUNT_PER_ADAPTER];
// Comman Input paramter array for all thread related ULTs to supply Adapter-Client Context input.
static ThreadInParams InParams[MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER];
// Array to store the adapter BDFs from simulated UMD, Save the adapter bdf in an array
static ADAPTER_BDF AdpaterSaved[MAX_NUM_ADAPTERS];
// Only for our ULT to supply dummy ProductFamily
static PRODUCT_FAMILY GetProductFamily(uint32_t AdapterIdx)
{
switch (AdapterIdx)
{
case 0: return IGFX_DG1;
case 1: return IGFX_ICELAKE;
case 2: return IGFX_TIGERLAKE_LP;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9: return IGFX_DG2;
case 11:
case 12:
case 13:
case 14:
case 15:
case 16: return IGFX_XE_HP_SDV;
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 27:
case 28:
case 29: return IGFX_PVC;
case 30:
case 31:
default: break;
}
return IGFX_COFFEELAKE;
}
// Only for our ULT to supply dummy GFXCORE_FAMILY
static GFXCORE_FAMILY GetRenderCoreFamily(uint32_t AdapterIdx)
{
switch (AdapterIdx)
{
case 0: return IGFX_XE_HP_CORE;
case 1: return IGFX_GEN11LP_CORE;
case 2: return IGFX_GEN12LP_CORE;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9: return IGFX_XE_HPG_CORE;
case 11:
case 12:
case 13:
case 14:
case 15:
case 16: return IGFX_XE_HP_CORE;
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 27:
case 28:
case 29: return IGFX_XE_HPC_CORE;
case 30:
case 31:
default: break;
}
return IGFX_GEN9_CORE;
}
// To simulate the UMDs/ClinentContexts per adapter i.e MAX_COUNT_PER_ADAPTER
// Increase MAX_COUNT_PER_ADAPTER value if there are more UMDs involved.
static GMM_CLIENT GetClientType(uint32_t CountIdx)
{
switch (CountIdx)
{
case 0: return GMM_D3D9_VISTA;
case 1: return GMM_D3D10_VISTA;
case 2: return GMM_D3D12_VISTA;
case 3: return GMM_EXCITE_VISTA;
case 4: return GMM_OCL_VISTA;
default: break;
}
return GMM_D3D9_VISTA;
}
// Returns the AdpaterSaved array value, Adapter BDFs based on input AdapterIdx.
static ADAPTER_BDF GetAdapterBDF(uint32_t AdapterIdx)
{
ADAPTER_BDF AdapterBDF={0,2,0,0};
if(AdapterIdx < MAX_NUM_ADAPTERS)
{
AdapterBDF.Bus = AdpaterSaved[AdapterIdx].Bus;
AdapterBDF.Device = AdpaterSaved[AdapterIdx].Device;
AdapterBDF.Function = AdpaterSaved[AdapterIdx].Function;
}
return AdapterBDF;
}
};
typedef MACommonULT GMM_MA_ULT_CONTEXT;
class CTestMA : public MACommonULT
{
public:
CTestMA();
~CTestMA();
static void SetUpTestCase();
static void TearDownTestCase();
};
#ifdef _WIN32
DWORD WINAPI Thread1(LPVOID lpParam);
#else
void *Thread1(void *lpParam);
#endif

View File

@ -0,0 +1,70 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmResourceULT.h"
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////
/// CTestCpuBltResource Constructor
///
/////////////////////////////////////////////////////////////////////////////////////
CTestCpuBltResource::CTestCpuBltResource()
{
}
/////////////////////////////////////////////////////////////////////////////////////
/// CTestCpuBltResource Constructor
///
/////////////////////////////////////////////////////////////////////////////////////
CTestCpuBltResource::~CTestCpuBltResource()
{
}
void CTestCpuBltResource::SetUpTestCase()
{
}
void CTestCpuBltResource::TearDownTestCase()
{
}
/// @brief ULT for 1D Resource
TEST_F(CTestCpuBltResource, TestCpuBlt1D)
{
}
/// @brief ULT for 2D Resource
TEST_F(CTestCpuBltResource, TestCpuBlt2D)
{
}
/// @brief ULT for 3D Resource
TEST_F(CTestCpuBltResource, TestCpuBlt3D)
{
}
/// @brief ULT for Cube Resource
TEST_F(CTestCpuBltResource, TestCpuBltCube)
{
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,517 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#include "GmmCommonULT.h"
//===========================================================================
// typedef:
// TEST_RESOURCE_TYPE_ENUM
//
// Description:
// Decribes Resource types to test
// when editing/adding existing/new enum, make sure to update corresponding
// string array CTestResource::TestResourceTypeStr[].
//----------------------------------------------------------------------------
typedef enum TEST_RESOURCE_TYPE_ENUM
{
TEST_RESOURCE_1D,
TEST_RESOURCE_2D,
TEST_RESOURCE_3D,
TEST_RESOURCE_CUBE,
TEST_RESOURCE_BUFFER,
TEST_RESOURCE_MAX
}TEST_RESOURCE_TYPE;
//===========================================================================
// typedef:
// TEST_RESOURCE_TYPE_ENUM
//
// Description:
// Decribes Resource Tile Types to test .
// when editing/adding existing/new enum, make sure to update corresponding
// string array CTestResource::TestTileTypeStr[].
//----------------------------------------------------------------------------
typedef enum TEST_TILE_TYPE_ENUM
{
TEST_LINEAR,
TEST_TILEX,
TEST_TILEY,
TEST_TILEYS,
TEST_TILEYF,
TEST_TILE_MAX
}TEST_TILE_TYPE;
//===========================================================================
// typedef:
// TEST_BPP_ENUM
//
// Description:
// Decribes BPP to test - 8, 16, 32, 64, 128 (Ignore 24/96 until need arises)
// when editing/adding existing/new enum, make sure to update corresponding
// string array CTestResource::TestBppStr[].
//----------------------------------------------------------------------------
typedef enum TEST_BPP_ENUM
{
TEST_BPP_8,
TEST_BPP_16,
TEST_BPP_32,
TEST_BPP_64,
TEST_BPP_128,
TEST_BPP_MAX
}TEST_BPP;
typedef enum TEST_MSAA_Samples
{
MSAA_None,
MSAA_2x,
MSAA_4x,
MSAA_8x,
MSAA_16x,
TEST_MSAA_MAX = MSAA_16x //Should be equal to last MSAA type
} TEST_MSAA;
//===========================================================================
// GmmLib ULT macros for size alignment. Compitable with 64-bit numbers.
//---------------------------------------------------------------------------
#define GMM_ULT_ALIGN(x, a) (((x) + ((a) - 1)) - (((x) + ((a) - 1)) & ((a) - 1))) // Alt implementation with bitwise not (~) has issue with uint32 align used with 64-bit value, since ~'ed value will remain 32-bit.
#define GMM_ULT_ALIGN_FLOOR(x, a) ((x) - ((x) & ((a) - 1)))
#define GMM_ULT_MAX(a, b) ((a) > (b)) ? (a) : (b)
#define GMM_ULT_MIN(a,b) (((a) < (b)) ? (a) : (b))
#define GMM_ULT_ALIGN_NP2(x, a) (((a) > 0) ? ((x) + (((a) - 1) - (((x) + ((a) - 1)) % (a)))) : (x)) //Next power of 2
#define GMM_ULT_MAX_MIPMAP 15
#define GMM_ULT_MAX_MIPTAIL_SLOTS 15
//////////////////////////////////////////////////////////////////////////
// typdef:
// TEST_MIPTAIL_SLOT_OFFSET_REC
//
// Description:
// Structure to hold the offset of the mip resources for unit level testing
//////////////////////////////////////////////////////////////////////////
typedef struct TEST_MIPTAIL_SLOT_OFFSET_REC
{
uint32_t X;
uint32_t Y;
uint32_t Z;
}TEST_MIPTAIL_SLOT_OFFSET;
/////////////////////////////////////////////////////////////////////////
/// Fixture class for Resource. - This is Resource Test Case to test
/// all generic resource types, tile types, bpp and special allocations.
/// Contains Base implementation and inherits CommonULT class
/////////////////////////////////////////////////////////////////////////
class CTestResource : public CommonULT
{
protected:
/////////////////////////////////////////////////////////////////////////////////////
/// Returns GMM format for given test BPP input.
///
/// @param[in] Bpp: test Bpp value
///
/// @return ::GMM_RESOURCE_FORMAT
/////////////////////////////////////////////////////////////////////////////////////
GMM_RESOURCE_FORMAT SetResourceFormat(TEST_BPP Bpp)
{
switch (Bpp)
{
case TEST_BPP_8: return GMM_FORMAT_GENERIC_8BIT;
case TEST_BPP_16: return GMM_FORMAT_GENERIC_16BIT;
case TEST_BPP_32: return GMM_FORMAT_GENERIC_32BIT;
case TEST_BPP_64: return GMM_FORMAT_GENERIC_64BIT;
case TEST_BPP_128: return GMM_FORMAT_GENERIC_128BIT;
default: break;
}
return GMM_FORMAT_INVALID;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Returns Bpp (bytes per pixel) for a given bpp (bits per pixel) enum.
///
/// @param[in] bpp: test bpp value
///
/// @return Bytes per pixel
/////////////////////////////////////////////////////////////////////////////////////
uint32_t GetBppValue(TEST_BPP bpp)
{
uint32_t Bpp = 0;
switch (bpp)
{
case TEST_BPP_8: Bpp = 8; break;
case TEST_BPP_16: Bpp = 16; break;
case TEST_BPP_32: Bpp = 32; break;
case TEST_BPP_64: Bpp = 64; break;
case TEST_BPP_128: Bpp = 128; break;
default: break;
}
return Bpp >> 3;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Set the tile flag in Gmm ResCreate Params
///
/// @param[in] Parms: Gmm Rescreate params
/// @param[in] Tile: Tile Type
///
/////////////////////////////////////////////////////////////////////////////////////
void SetTileFlag(GMM_RESCREATE_PARAMS &Params, TEST_TILE_TYPE Tile)
{
switch (Tile)
{
case TEST_LINEAR:
Params.Flags.Info.Linear = 1;
break;
case TEST_TILEX:
Params.Flags.Info.TiledX = 1;
break;
case TEST_TILEY:
Params.Flags.Info.TiledY = 1;
break;
case TEST_TILEYF:
Params.Flags.Info.TiledY = 1;
Params.Flags.Info.TiledYf = 1;
break;
case TEST_TILEYS:
Params.Flags.Info.TiledY = 1;
Params.Flags.Info.TiledYs = 1;
break;
default: break;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Set the tile flag in Gmm Custom ResCreate Params
///
/// @param[in] Parms: Gmm Rescreate params
/// @param[in] Tile: Tile Type
///
/////////////////////////////////////////////////////////////////////////////////////
void SetTileFlag_Custom(GMM_RESCREATE_CUSTOM_PARAMS& Params, TEST_TILE_TYPE Tile)
{
switch (Tile)
{
case TEST_LINEAR:
Params.Flags.Info.Linear = 1;
break;
case TEST_TILEX:
Params.Flags.Info.TiledX = 1;
break;
case TEST_TILEY:
Params.Flags.Info.TiledY = 1;
break;
case TEST_TILEYF:
Params.Flags.Info.TiledY = 1;
Params.Flags.Info.TiledYf = 1;
break;
case TEST_TILEYS:
Params.Flags.Info.TiledY = 1;
Params.Flags.Info.TiledYs = 1;
break;
default: break;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Sets Resource Type in GmmParams
///
/// @param[in] Params: GmmParams
/// @param[in] ResType: Resource type
///
/////////////////////////////////////////////////////////////////////////////////////
void SetResType(GMM_RESCREATE_PARAMS& Params, TEST_RESOURCE_TYPE ResType)
{
Params.Type = static_cast<GMM_RESOURCE_TYPE>((ResType == TEST_RESOURCE_BUFFER) ? ResType + 2 : ResType + 1);
}
/////////////////////////////////////////////////////////////////////////////////////
/// Sets RenderTarget or Depth Gpu Flags in GmmParams
///
/// @param[in] Params: GmmParams
/// @param[in] IsRT: true for RT, false for Depth
///
/////////////////////////////////////////////////////////////////////////////////////
void SetResGpuFlags(GMM_RESCREATE_PARAMS& Params, bool IsRT)
{
if (IsRT)
{
Params.Flags.Gpu.Depth = 0;
Params.Flags.Gpu.RenderTarget = 1;
}
else
{
Params.Flags.Gpu.Depth = 1;
Params.Flags.Gpu.RenderTarget = 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Sets ArraySize in GmmParams
///
/// @param[in] Params: GmmParams
/// @param[in] Size: Array Size
///
/////////////////////////////////////////////////////////////////////////////////////
void SetResArraySize(GMM_RESCREATE_PARAMS& Params, int Size)
{
Params.ArraySize = Size;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Get the Tile dimension and H/V Align for MSS and MCS surfaces
///
/// @param[in] Bpp: bits per pixel
/// @param[in] isRT: Request is for RT or Depth MSS
/// @param[in] Tiling: Tile Type
/// @param[in] MSAA: Num of Samples
/// @param[out] HAlign: H Align for MSS
/// @param[out] VAlign: V Align for MSS
/// @param[out] TileDimX: Tile Width for given Tile, Resource, bpp
/// @param[out] TileDimY: Tile Height for given Tile, Resource, bpp
/// @param[out] MCSHAlign: H Align for MCS
/// @param[out] MCSVAlign: V Align for MCS
///
/////////////////////////////////////////////////////////////////////////////////////
void GetAlignmentAndTileDimensionsForMSAA(TEST_BPP Bpp, bool isRT, TEST_TILE_TYPE Tiling, TEST_MSAA MSAA,
uint32_t& TileDimX, uint32_t& TileDimY, uint32_t& HAlign, uint32_t& VAlign,
uint32_t& ExpectedMCSBpp, uint32_t &MCSHAlign, uint32_t &MCSVAlign)
{
const uint32_t MSSTileSize[TEST_TILE_MAX][TEST_BPP_MAX][2] = {
{ { 64, 1 },{ 64, 1 },{ 64, 1 },{ 64, 1 },{ 64, 1 } }, //Linear - no Tile Size, but min PitchAlign = 64
{ { 512, 8 },{ 512, 8 },{ 512, 8 },{ 512, 8 },{ 512, 8 } }, //TileX
{ { 128, 32 },{ 128, 32 },{ 128, 32 },{ 128, 32 },{ 128, 32 } }, //TileY
{ { 256, 256 },{ 512, 128 },{ 512, 128 },{ 1024, 64 },{ 1024, 64 } }, //TileYs
{ { 64, 64 },{ 128, 32 },{ 128, 32 },{ 256, 16 },{ 256, 16 } } //TileYf
};
uint32_t WMul, HMul;
HAlign = 16; // RT H/VAlign
VAlign = 4;
if (!isRT)
{
HAlign = (Bpp == TEST_BPP_16) ? 8 : 4; //Depth 16bit = 8x4, ow 4x4
VAlign = 4;
MCSHAlign = 4; //MCS uses base H/VAlign for 8bpp
}
uint32_t Tile[2] = { MSSTileSize[Tiling][Bpp][0], MSSTileSize[Tiling][Bpp][1] };
if (Tiling == TEST_TILEYS || Tiling == TEST_TILEYF)
{
GetInterleaveMSSPattern(MSAA, WMul, HMul);
//Std Tiling interleaves MSAA into 1x, decreasing std Tile size for MSAA'd sample
//Std Tiling types should have std size alignment always
Tile[0] = HAlign = (isRT) ? (MSSTileSize[Tiling][Bpp][0] / WMul) : MSSTileSize[Tiling][Bpp][0];
Tile[1] = VAlign = (isRT) ? (MSSTileSize[Tiling][Bpp][1] / HMul) : MSSTileSize[Tiling][Bpp][1];
HAlign /= pow(2.0, Bpp); //Unit alignment in pixels
}
TileDimX = Tile[0];
TileDimY = Tile[1];
ExpectedMCSBpp = (MSAA == MSAA_2x || MSAA == MSAA_4x) ? 1 :
(MSAA == MSAA_8x) ? 4 : 8;
uint32_t ExpectedMcsBppIdx = log2(ExpectedMCSBpp);
MCSHAlign = isRT ? HAlign : MCSHAlign; //MCS uses base H/V ALign for 8bpp
MCSVAlign = VAlign;
MCSHAlign = (isRT && (Tiling == TEST_TILEYS || Tiling == TEST_TILEYF)) ?
MSSTileSize[Tiling][ExpectedMcsBppIdx][0] / (WMul * ExpectedMCSBpp) : //Std Tile dim in pixels
(Tiling == TEST_TILEYS || Tiling == TEST_TILEYF) ?
MSSTileSize[Tiling][ExpectedMcsBppIdx][0] / ExpectedMCSBpp : MCSHAlign; //For legacy tile, MCS alignment is base (RT or Depth) alignment
MCSVAlign = (isRT && (Tiling == TEST_TILEYS || Tiling == TEST_TILEYF)) ? MSSTileSize[Tiling][ExpectedMcsBppIdx][1] / HMul :
(Tiling == TEST_TILEYS || Tiling == TEST_TILEYF) ? MSSTileSize[Tiling][ExpectedMcsBppIdx][1] : MCSVAlign;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Get the interleave pattern for given Num Samples
///
/// @param[in] MSAA: Num of Samples
/// @param[out] WidthMultiplier: Number of samples arranged side-by-side
/// @param[out] HeightMultiplier: Number of samples arranged top-bottom
///
/////////////////////////////////////////////////////////////////////////////////////
void GetInterleaveMSSPattern(TEST_MSAA MSAA, uint32_t& WidthMultiplier, uint32_t& HeightMultiplier)
{
WidthMultiplier = 1; HeightMultiplier = 1;
switch (MSAA)
{
case MSAA_2x: WidthMultiplier = 2; break;
case MSAA_4x: WidthMultiplier = 2; HeightMultiplier = 2; break;
case MSAA_8x: WidthMultiplier = 4; HeightMultiplier = 2; break;
case MSAA_16x:WidthMultiplier = 4; HeightMultiplier = 4; break;
default: break;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Verifies if HAlign matches the expected value. Fails test if value doesn't match
///
/// @param[in] ResourceInfo: ResourceInfo returned by GmmLib
/// @param[in] ExpectedValue: expected value to check against
/////////////////////////////////////////////////////////////////////////////////////
template <bool Verify>
void VerifyResourceHAlign(GMM_RESOURCE_INFO *ResourceInfo, uint32_t ExpectedValue)
{
if(Verify)
{
EXPECT_EQ(ExpectedValue, ResourceInfo->GetHAlign());
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Verifies if HAlign matches the expected value. Fails test if value doesn't match
///
/// @param[in] ResourceInfo: ResourceInfo returned by GmmLib
/// @param[in] ExpectedValue: expected value to check against
/////////////////////////////////////////////////////////////////////////////////////
template <bool Verify>
void VerifyResourceVAlign(GMM_RESOURCE_INFO *ResourceInfo, uint32_t ExpectedValue)
{
if(Verify)
{
EXPECT_EQ(ExpectedValue, ResourceInfo->GetVAlign());
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Verifies if Pitch (in bytes) matches the expected value. Fails test if value
/// doesn't match
///
/// @param[in] ResourceInfo: ResourceInfo returned by GmmLib
/// @param[in] ExpectedValue: expected value to check against
/////////////////////////////////////////////////////////////////////////////////////
template <bool Verify>
void VerifyResourcePitch(GMM_RESOURCE_INFO *ResourceInfo, uint32_t ExpectedValue)
{
if(Verify)
{
EXPECT_EQ(ExpectedValue, ResourceInfo->GetRenderPitch());
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Verifies if Pitch in tiles matches the expected value. Fails test if value
/// doesn't match
///
/// @param[in] ResourceInfo: ResourceInfo returned by GmmLib
/// @param[in] ExpectedValue: expected value to check against
/////////////////////////////////////////////////////////////////////////////////////
template <bool Verify>
void VerifyResourcePitchInTiles(GMM_RESOURCE_INFO *ResourceInfo, uint32_t ExpectedValue)
{
if(Verify)
{
EXPECT_EQ(ExpectedValue, ResourceInfo->GetRenderPitchTiles());
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Verifies if Size matches the expected value. Fails test if value doesn't match
///
/// @param[in] ResourceInfo: ResourceInfo returned by GmmLib
/// @param[in] ExpectedValue: expected value to check against
/////////////////////////////////////////////////////////////////////////////////////
template <bool Verify>
void VerifyResourceSize(GMM_RESOURCE_INFO *ResourceInfo, uint64_t ExpectedValue)
{
if(Verify)
{
EXPECT_EQ(ExpectedValue, ResourceInfo->GetSizeMainSurface());
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Verifies if QPitch matches the expected value. Fails test if value doesn't match
///
/// @param[in] ResourceInfo: ResourceInfo returned by GmmLib
/// @param[in] ExpectedValue: expected value to check against
/////////////////////////////////////////////////////////////////////////////////////
template <bool Verify>
void VerifyResourceQPitch(GMM_RESOURCE_INFO *ResourceInfo, uint64_t ExpectedValue)
{
if(Verify)
{
EXPECT_EQ(ExpectedValue, ResourceInfo->GetQPitch());
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Verifies if Tile4 info flag is set or not. Fails test if Tile4 flag is not set
///
/// @param[in] ResourceInfo: ResourceInfo returned by GmmLib
/// @param[in] ExpectedValue: expected value to check against
/////////////////////////////////////////////////////////////////////////////////////
template <bool Verify>
void VerifyResourceTile4(GMM_RESOURCE_INFO *ResourceInfo, bool ExpectedValue)
{
if(Verify)
{
EXPECT_EQ(true, (GMM_IS_4KB_TILE(ResourceInfo->GetResFlags())));
}
}
public:
CTestResource();
~CTestResource();
static void SetUpTestCase();
static void TearDownTestCase();
};
/////////////////////////////////////////////////////////////////////////
/// Fixture class for Resources targeted for CpuBlt. This is CpuBlt resource
/// test case. Inherits CTestResource class.
/// @see CTestResource class
/////////////////////////////////////////////////////////////////////////
class CTestCpuBltResource : public CTestResource
{
public:
CTestCpuBltResource();
~CTestCpuBltResource();
static void SetUpTestCase();
static void TearDownTestCase();
};
/////////////////////////////////////////////////////////////////////////
/// Helper function - builds list of input tuples
///
/// @param[in/out] List: vector of tuple<int,int,int,bool,int,int>
/// @param[in] maxTestDimension: Number of elements in TestDimensions[]
/// @param[in] TestArray: Number fo elements in TestArraySize
///
/// @return Number of tuples in the list
/// @see GmmGen9ResourceULT.cpp
/////////////////////////////////////////////////////////////////////////
int BuildInputIterator(std::vector<std::tuple<int, int, int, bool, int, int>> &List, int maxTestDimension, int TestArray);

View File

@ -0,0 +1,42 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "stdafx.h"
using namespace std;
int g_argc;
char **g_argv;
int main(int argc, char *argv[])
{
int FailCount = 0;
testing::InitGoogleTest(&argc, argv);
g_argc = argc;
g_argv = argv;
FailCount += RUN_ALL_TESTS();
return FailCount;
}

View File

@ -0,0 +1,82 @@
========================================================================
CONSOLE APPLICATION : GmmLibULT Project Overview
========================================================================
GMM ULT for the GMM Cache Policy.
GmmLibULT.vcxproj
This is the main project file.
GmmLibULT.vcxproj.filters
This is the filters file for VC++ project.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
GmmLibULT.cpp
This is the main application source file.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named GmmLibULT.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
This ULT is divided into 2 parts.
1. CompileTime ULT - Runs with every Gmmlib build and KMD build
How to trigger Test cases through commandline:
i. Run all Compile Time TestCases --> GmmULT.exe CTest*.*
ii.Run Specific TestCase --> GmmULT.exe CTestGen9CachePolicy.*
2. RunTime ULT - Runnable on Target system. Have to run it manually - not qualified to run on Host/Dev systems
How to trigger Test cases through commandline:
i. CachePolicy ULT --> GmmULT.exe RTestGen9CachePolicy.*
ii. Vulkan Generic Resource --> GmmULT.exe RTestVulkanResource.*Generic*
ii. Vulkan Sparse Resource --> GmmULT.exe RTestVulkanResource.*Sparse*
To Run the Test on target
i. Download Driver along with Test Tools, which has ExCITE DLL or build ExCITE DLL on your dev system with the installed driver source
ii. Install driver and copy DLL in either C:\Windows\System32 (for 64-bit app/DLL) or C:\Windows\SysWoW64 or place it in ULT executable Directory
iii. Specify commandline and run GMMULT.exe
Test Case:
> Test Case is defined by FIXTURE class -> Test Case = FIXTURE Class
> Ex. class CTestResource : public testing::Test --> CTestResource is FIXTURE class
Test:
> Test resides in FIXTURE. FIXTURE class has multiple tests
> Ex. TEST_F(CTestResource, test2DResource) --> test2DResource is a test of test case - CTestResource
SetUp() vs SetUpTestCase()
> SetUp() -> gets called for all the tests in a test case. This is per-test setup/tear down
> SetUpTestCase() -> When multiple tests in a test case share resource or needs same set up, then instead of repeating set up
per test, SetUpTestCase gets called once per test case and all the tests inside a test case, use same set up.
To exclude tests from execution
> --gtest_filter=POSTIVE_PATTERNS[-NEGATIVE_PATTERNS]
> Ex. --gtest_filter=-ABC.*:BCD.*
What happens when test/test case is triggered
TEST_F(CTestGen9Resource, Test2DTileYResource) --> first instance of test in CTestGen9Resource FIXTURE test case
1. CTestGen9Resource::SetUpTestCase() --> this sets up platform --> This step is skipped if this is subsequence test instances in test case.
i. Calls CommonULT::SetUpTestCase() --> GmmInitGlobalContext() and other initialization
2. CTestResource::CTestResource()
3. CTestGen9Resource::CTestGen9Resource()
4. Test_F body --> test execution
5. CTestGen9Resource::~CTestGen9Resource()
6. CTestResource::~CTestResource( )
7. CommonULT::~CommonULT() --> Destroys Global Context
8. void CTestGen9Resource::TearDownTestCase() --> only if this is last instance of test in test case
CompileTime cmdline: $(TargetDir)$(TargetFileName) --gtest_filter=CTestResource.Test2DTileYsResource
To debug failures, add the following in the command line argument: --gtest_break_on_failure
This will cause an assert to be hit whenever a test fails. You can use the call stack to go back to the failing test and debug.
/////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
//Abstract: include file for standard system include files,
// or project specific include files that are used frequently
#pragma once
#ifndef _WIN32
#include "../../inc/portable_compiler.h"
#endif
#include "targetver.h"
#include <stdio.h>
#include <math.h>
#ifdef _WIN32
#include <tchar.h>
#include <windows.h>
#endif
#include <iostream>
#include "gtest.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "sharedata.h"
#include "../../inc/common/igfxfmid.h"
#include "../../inc/common/sku_wa.h"
#include "../../inc/common/gfxmacro.h"
#include "../inc/External/Common/GmmCommonExt.h"
#include "../inc/External/Common/GmmPlatformExt.h"
#include "../inc/External/Common/GmmCachePolicy.h"
#include "../inc/External/Common/GmmTextureExt.h"
#include "../inc/External/Common/GmmResourceInfoExt.h"
#include "../inc/External/Common/GmmResourceInfo.h"
#include "../inc/External/Common/GmmUtil.h"
#include "../inc/External/Common/GmmInfoExt.h"
#include "../inc/External/Common/GmmInfo.h"
#include "../inc/External/Common/GmmClientContext.h"
#include "../inc/External/Common/GmmPageTableMgr.h"
#include "../inc/External/Common/GmmLibDll.h"
#include "../inc/External/Common/GmmLibDllName.h"
#ifdef __cplusplus
}
#endif
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#ifndef STATUS_UNSUCCESSFUL
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#endif
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif
extern int g_argc;
extern char** g_argv;

View File

@ -0,0 +1,34 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#if _WIN32
#include <SDKDDKVer.h>
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
// File intended for same-folder-inclusion by CpuSwizzleBlt.c to reroute
// standard asserts when compiled in GMM.
#pragma once
#ifdef __GMM
#include "External/Common/GmmInternal.h"
#define assert __GMM_ASSERT
#else
#include <assert.h>
#endif

View File

@ -0,0 +1,319 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#include "GmmLog.h"
#if GMM_LOG_AVAILABLE
#include "Internal/Common/GmmLibInc.h"
#include "Internal/Common/GmmLogger.h"
#if _WIN32
#include <process.h>
#include <memory>
#else
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fstream>
#include <linux/limits.h>
#endif
/// Logger instance shared by all of GmmLib within a process
#if(_DEBUG || _RELEASE_INTERNAL)
GmmLib::Logger &GmmLoggerPerProc = GmmLib::Logger::CreateGmmLogSingleton();
#endif
#if _WIN32
namespace spdlog
{
namespace sinks
{
/////////////////////////////////////////////////////////////////////////////////////
/// class defines a sink which prints the messages to the debugger
/////////////////////////////////////////////////////////////////////////////////////
class Debugger : public sink
{
void log(const details::log_msg &msg) override
{
OutputDebugString(GMM_PREFIX_STR);
OutputDebugString(msg.formatted.str().c_str());
}
void flush()
{
}
};
}
}
#endif
/////////////////////////////////////////////////////////////////////////////////////
/// Initializes Gmm Logger
///
/// @return true if initialized successfully. false otherwise
/////////////////////////////////////////////////////////////////////////////////////
bool GmmLib::Logger::GmmLogInit()
{
std::string LogFilePath;
std::string ProcPath;
std::string ProcName;
int Pid = 0;
// Get logging method
#if _WIN32
uint32_t regkeyVal = 0;
if(Utility::GmmUMDReadRegistryFullPath(GMM_LOG_REG_KEY_SUB_PATH, GMM_LOG_TO_FILE, &regkeyVal))
{
LogMethod = regkeyVal ? ToFile : ToOSLog;
}
if(Utility::GmmUMDReadRegistryFullPath(GMM_LOG_REG_KEY_SUB_PATH, GMM_LOG_LEVEL_REGKEY, &regkeyVal))
{
switch(static_cast<GmmLogLevel>(regkeyVal))
{
case Trace:
LogLevel = spdlog::level::trace;
break;
case Info:
LogLevel = spdlog::level::info;
break;
case Error:
LogLevel = spdlog::level::err;
break;
case Critical:
LogLevel = spdlog::level::critical;
break;
case Off:
default:
LogLevel = spdlog::level::off;
break;
}
}
#endif
if(LogLevel == spdlog::level::off)
{
return false;
}
try
{
if(LogMethod == ToFile)
{
// Get process name
#if _WIN32
TCHAR ProcPathTChar[MAX_PATH];
GetModuleFileName(NULL, ProcPathTChar, MAX_PATH);
ProcPath = std::string(ProcPathTChar);
size_t PosOfLastSlash = ProcPath.find_last_of("\\") + 1;
size_t PosOfLastDot = ProcPath.find_last_of(".");
if(PosOfLastDot <= PosOfLastSlash || PosOfLastDot >= ProcPath.length() || PosOfLastSlash >= ProcPath.length())
{
ProcName = GMM_UNKNOWN_PROCESS;
}
else
{
ProcName = ProcPath.substr(PosOfLastSlash, PosOfLastDot - PosOfLastSlash);
}
#else
ProcPath = "Unknown_Proc_Path";
ProcName = GMM_UNKNOWN_PROCESS;
std::ifstream file;
file.open("/proc/self/cmdline");
if(file.is_open())
{
// Get process name
getline(file, ProcPath);
size_t PosOfLastSlash = ProcPath.find_last_of("/") + 1;
if(PosOfLastSlash >= ProcPath.length())
{
ProcName = GMM_UNKNOWN_PROCESS;
}
else
{
// "length-1" to remove null character
ProcName = ProcPath.substr(PosOfLastSlash, ProcPath.length() - 1);
}
file.close();
}
#endif
// Get process ID
#if _WIN32
Pid = _getpid();
#else
Pid = getpid();
#endif
std::string PidStr = std::to_string(Pid);
// TODO: Multiple GmmLib instance can be running in the same process. In that case, the file name will be
// the same for two instances. Figure out a way to differentiate between the two instances.
#if _WIN32
LogFilePath = std::string("c:\\") + std::string(GMM_LOG_FILENAME) + "_" + ProcName + "_" + PidStr;
#else
LogFilePath = std::string(".//") + std::string(GMM_LOG_FILENAME) + "" + ProcName + "_" + PidStr;
#endif
// Create logger
SpdLogger = spdlog::rotating_logger_mt(GMM_LOGGER_NAME,
LogFilePath,
GMM_LOG_FILE_SIZE,
GMM_ROTATE_FILE_NUMBER);
// Log process path
SpdLogger->set_pattern("Process path: %v");
SpdLogger->info(ProcPath.c_str());
}
else
{
#if defined(_WIN32)
// Log to debugger
auto debugger_sink = std::make_shared<spdlog::sinks::Debugger>();
SpdLogger = std::make_shared<spdlog::logger>(GMM_LOGGER_NAME, debugger_sink);
#elif defined(__ANDROID__)
// Log to logcat
SpdLogger = spdlog::android_logger(GMM_LOGGER_NAME, GMM_LOG_TAG);
#elif defined(__linux__)
// Log to syslog
SpdLogger = spdlog::syslog_logger(GMM_LOGGER_NAME, GMM_LOG_TAG, 1 /*Log Pid*/);
#else
__GMM_ASSERT(0);
return false;
#endif
}
}
catch(const spdlog::spdlog_ex &ex)
{
__GMM_ASSERT(0);
return false;
}
// Set log level
SpdLogger->set_level(LogLevel);
// Set log pattern
SpdLogger->set_pattern("[%T.%e] [Thread %t] [%l] %v"); // [Time] [Thread id] [Log Level] [Text to Log]
return true;
}
/////////////////////////////////////////////////////////////////////////////////////
/// Gmm Logger constructor
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::Logger::Logger()
: LogMethod(ToOSLog),
LogLevel(spdlog::level::off)
{
if(!GmmLogInit())
{
spdlog::set_level(spdlog::level::off);
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Gmm Logger Destructor
/////////////////////////////////////////////////////////////////////////////////////
GmmLib::Logger::~Logger()
{
if(SpdLogger)
{
SpdLogger->flush();
}
}
/////////////////////////////////////////////////////////////////////////////////////
/// Gmm Logger C wrappers
/////////////////////////////////////////////////////////////////////////////////////
#if !_WIN32
// Linux/Android replacement for MS version of _vscprintf
inline int vscprintf_lin(const char *msg, va_list args)
{
char c;
va_list args_cpy;
// Copy `args' to prevent internal pointer modification from vsnprintf
va_copy(args_cpy, args);
int len = vsnprintf(&c, 1, msg, args_cpy);
va_end(args_cpy);
return len;
}
#endif
/////////////////////////////////////////////////////////////////////////////////////
/// Gmm Logger C wrapper for GMM_LOG_* Macros
/////////////////////////////////////////////////////////////////////////////////////
extern "C" void GMM_STDCALL GmmLibLogging(GmmLogLevel Level, const char *str, ...)
{
va_list args;
if(GmmLoggerPerProc.SpdLogger)
{
va_start(args, str);
#if _WIN32
const size_t length = _vscprintf(str, args);
#else
const size_t length = vscprintf_lin(str, args);
#endif
char *temp = new char[length + 1];
if(temp)
{
#if _WIN32
vsprintf_s(temp, length + 1, str, args);
#else
vsnprintf(temp, length + 1, str, args);
#endif
switch(Level)
{
case Trace:
// Set log level to trace if we want trace msges to be printed
//GmmLoggerPerProc.SpdLogger->set_level(spdlog::level::trace);
GmmLoggerPerProc.SpdLogger->trace(temp);
break;
case Info:
// Set log level to info if we want info msges to be printed
//GmmLoggerPerProc.SpdLogger->set_level(spdlog::level::info);
GmmLoggerPerProc.SpdLogger->info(temp);
break;
case Error:
GmmLoggerPerProc.SpdLogger->critical(temp);
break;
default:
break;
}
delete[] temp;
}
}
va_end(args);
}
#endif //#if GMM_LOG_AVAILABLE

View File

@ -0,0 +1,158 @@
/*==============================================================================
Copyright(c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files(the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and / or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
============================================================================*/
#pragma once
#if (_DEBUG || _RELEASE_INTERNAL) && !__GMM_KMD__
// Not doing #if__cplusplus >= 201103L check because partial C++11 support may
// work for this. We also want to catch C++11 unavailability due to not setting
// compiler options.
#if (_MSC_VER >= 1800) // VS 2013+
#define GMM_LOG_AVAILABLE 1
#elif((__clang_major__ > 3) || ((__clang_major__ == 3) && (__clang_minor__ >= 5))) // clang 3.5+
#define GMM_LOG_AVAILABLE 1
#elif((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))) // g++ 4.8+
#define GMM_LOG_AVAILABLE 1
#else
#define GMM_LOG_AVAILABLE 0
// Print out messages if GmmLog was disabled due to compiler issues
#define STRING2(x) #x
#define STRING(x) STRING2(x)
#if (defined __GNUC__)
#pragma message "Detected g++ " STRING(__GNUC__) "." STRING(__GNUC_MINOR__) ". Minimum compiler version required for GmmLog is GCC 4.8.1. Disabling GmmLog."
#elif (defined __clang__)
#pragma message "Detected clang " STRING(__clang_major__) "." STRING(__clang_minor__) ". Minimum compiler version required for GmmLog is clang 3.5. Disabling GmmLog."
#elif (defined _MSC_VER)
#pragma message("Detected MSVC++ version " STRING(_MSC_VER) ". Minimum compiler version required for GmmLog is MSVC++ 1800. Disabling GmmLog")
#else
#pragma message "Unknown compiler. Disabling GmmLog."
#endif
#undef STRING2
#undef STRING
#endif
#elif (_DEBUG || _RELEASE_INTERNAL) && __GMM_KMD__ && _WIN32
#define GMM_KMD_LOG_AVAILABLE 1
/////////////////////////////////////////////////////////////////////////////////////
/// GMM_KMD_LOG
/// Gmm logging macro to log a message in KMD mode. Exmaple:
/// GMM_KMD_LOG("Math Addition: %d + %d = %d \r\n", 1, 1, 2);
/////////////////////////////////////////////////////////////////////////////////////
#define GMM_KMD_LOG(message, ...) \
{ \
DWORD CurrentProcessId = (DWORD) (ULONG_PTR)PsGetCurrentProcessId(); \
const WCHAR *format = L"%s%d.txt"; \
WCHAR FileName[] = L"C:\\Intel\\IGfx\\GmmKmd_Proc_"; \
WCHAR FullFileName[KM_FILENAME_LENGTH]; \
\
KmGenerateLogFileName(&FullFileName[0], format, FileName, CurrentProcessId); \
\
KM_FILE_IO_OBJ *pGmmKmdLog = KmFileOpen(pHwDevExt, FullFileName, false, false, true); \
if (pGmmKmdLog != NULL) \
{ \
KmFilePrintf(pGmmKmdLog, message, __VA_ARGS__); \
KmFileClose(pGmmKmdLog, false); \
} \
} \
#else // else if Release driver || KMD
#define GMM_LOG_AVAILABLE 0
#endif
#if GMM_LOG_AVAILABLE
typedef enum GmmLogLevel
{
Off = 0,
Trace,
Info,
Error, // default
Critical,
}GmmLogLevel;
#ifdef __cplusplus
#include <iostream>
#define GMM_LOG_FILE_SIZE 1024 * 1024 * 5 // Once log reaches this size, it will start in new file
#define GMM_ROTATE_FILE_NUMBER 3 // Once log is full, it'll save old log with .1/.2/.3 in name, and then start with .1
#define GMM_LOG_MASSAGE_MAX_SIZE 1024
#define GMM_LOGGER_NAME "gmm_logger"
#define GMM_LOG_FILENAME "gmm_log"
#define GMM_LOG_TAG "GmmLib"
#define GMM_UNKNOWN_PROCESS "Unknown_Proc"
#define GMM_PREFIX_STR "INTC GMM SPD: "
#if _WIN32
#define GMM_LOG_REG_KEY_SUB_PATH "SOFTWARE\\Intel\\IGFX\\GMMLOG\\"
#define GMM_LOG_TO_FILE "LogToFile"
#define GMM_LOG_LEVEL_REGKEY "LogLevel" // GmmLogLevel
#endif //#if _WIN32
extern "C" void GmmLibLogging(GmmLogLevel Level, const char* str, ...);
#define GMM_LOG_TRACE(message, ...) GmmLibLogging(Trace, message, ##__VA_ARGS__)
#define GMM_LOG_TRACE_IF(expression, message, ...) if(expression) { GmmLibLogging(Trace, message, ##__VA_ARGS__);}
#define GMM_LOG_INFO(message, ...) GmmLibLogging(Info, message, ##__VA_ARGS__)
#define GMM_LOG_INFO_IF(expression, message, ...) if(expression) { GmmLibLogging(Info, message, ##__VA_ARGS__);}
#define GMM_LOG_ERROR(message, ...) GmmLibLogging(Error, message, ##__VA_ARGS__)
#define GMM_LOG_ERROR_IF(expression, message, ...) if(expression) { GmmLibLogging(Error, message, ##__VA_ARGS__);}
#else // else C
// Fwd Declarations of C-wrapper functions used for Logging
void GmmLibLogging(GmmLogLevel Level, const char* str, ...);
#define GMM_LOG_TRACE(message, ...) GmmLibLogging(Trace, message, ##__VA_ARGS__)
#define GMM_LOG_TRACE_IF(expression, message, ...) if(expression) { GmmLibLogging(Trace, message, ##__VA_ARGS__);}
#define GMM_LOG_INFO(message, ...) GmmLibLogging(Info, message, ##__VA_ARGS__)
#define GMM_LOG_INFO_IF(expression, message, ...) if(expression) { GmmLibLogging(Info, message, ##__VA_ARGS__);}
#define GMM_LOG_ERROR(message, ...) GmmLibLogging(Error, message, ##__VA_ARGS__)
#define GMM_LOG_ERROR_IF(expression, message, ...) if(expression) { GmmLibLogging(Error, message, ##__VA_ARGS__);}
#endif //#ifdef __cplusplus
#else // else Gmm Log not available
#define GMM_LOG_TRACE(message, ...)
#define GMM_LOG_TRACE_IF(expression, message, ...)
#define GMM_LOG_INFO(message, ...)
#define GMM_LOG_INFO_IF(expression, message, ...)
#define GMM_LOG_ERROR(message, ...)
#define GMM_LOG_ERROR_IF(expression, message, ...)
#endif //#if _WIN32
#if GMM_KMD_LOG_AVAILABLE
#else
#define GMM_KMD_LOG(message, ...)
#endif

View File

@ -0,0 +1,5 @@
This library has been taken from https://github.com/gabime/spdlog under MIT license.
GmmLib is using this library for logging to a file, log to debugger (Windows),
log to logcat (Android) and log to syslog (Linux) with format similar to python print()
under Debug and Release Internal modes.

Some files were not shown because too many files have changed in this diff Show More