1415 lines
45 KiB
C++
1415 lines
45 KiB
C++
/**************************************************************************
|
|
*
|
|
* Copyright 2012-2021 VMware, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
* 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
|
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
|
|
*
|
|
* The above copyright notice and this permission notice (including the
|
|
* next paragraph) shall be included in all copies or substantial portions
|
|
* of the Software.
|
|
*
|
|
**************************************************************************/
|
|
|
|
/*
|
|
* Shader.cpp --
|
|
* Functions that manipulate shader resources.
|
|
*/
|
|
|
|
|
|
#include "Shader.h"
|
|
#include "ShaderParse.h"
|
|
#include "State.h"
|
|
#include "Query.h"
|
|
|
|
#include "Debug.h"
|
|
#include "Format.h"
|
|
|
|
#include "tgsi/tgsi_ureg.h"
|
|
#include "util/u_gen_mipmap.h"
|
|
#include "util/u_sampler.h"
|
|
#include "util/format/u_format.h"
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreateEmptyShader --
|
|
*
|
|
* Update the driver's currently bound constant buffers.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void *
|
|
CreateEmptyShader(Device *pDevice,
|
|
enum pipe_shader_type processor)
|
|
{
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
struct ureg_program *ureg;
|
|
const struct tgsi_token *tokens;
|
|
uint nr_tokens;
|
|
|
|
if (processor == PIPE_SHADER_GEOMETRY) {
|
|
return NULL;
|
|
}
|
|
|
|
ureg = ureg_create(processor);
|
|
if (!ureg)
|
|
return NULL;
|
|
|
|
ureg_END(ureg);
|
|
|
|
tokens = ureg_get_tokens(ureg, &nr_tokens);
|
|
if (!tokens)
|
|
return NULL;
|
|
|
|
ureg_destroy(ureg);
|
|
|
|
struct pipe_shader_state state;
|
|
memset(&state, 0, sizeof state);
|
|
state.tokens = tokens;
|
|
|
|
void *handle;
|
|
switch (processor) {
|
|
case PIPE_SHADER_FRAGMENT:
|
|
handle = pipe->create_fs_state(pipe, &state);
|
|
break;
|
|
case PIPE_SHADER_VERTEX:
|
|
handle = pipe->create_vs_state(pipe, &state);
|
|
break;
|
|
case PIPE_SHADER_GEOMETRY:
|
|
handle = pipe->create_gs_state(pipe, &state);
|
|
break;
|
|
default:
|
|
handle = NULL;
|
|
assert(0);
|
|
}
|
|
assert(handle);
|
|
|
|
ureg_free_tokens(tokens);
|
|
|
|
return handle;
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreateEmptyShader --
|
|
*
|
|
* Update the driver's currently bound constant buffers.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
DeleteEmptyShader(Device *pDevice,
|
|
enum pipe_shader_type processor, void *handle)
|
|
{
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
|
|
if (processor == PIPE_SHADER_GEOMETRY) {
|
|
assert(handle == NULL);
|
|
return;
|
|
}
|
|
|
|
assert(handle != NULL);
|
|
switch (processor) {
|
|
case PIPE_SHADER_FRAGMENT:
|
|
pipe->delete_fs_state(pipe, handle);
|
|
break;
|
|
case PIPE_SHADER_VERTEX:
|
|
pipe->delete_vs_state(pipe, handle);
|
|
break;
|
|
case PIPE_SHADER_GEOMETRY:
|
|
pipe->delete_gs_state(pipe, handle);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* SetConstantBuffers --
|
|
*
|
|
* Update the driver's currently bound constant buffers.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
static void
|
|
SetConstantBuffers(enum pipe_shader_type shader_type, // IN
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT StartBuffer, // IN
|
|
UINT NumBuffers, // IN
|
|
const D3D10DDI_HRESOURCE *phBuffers) // IN
|
|
{
|
|
Device *pDevice = CastDevice(hDevice);
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
|
|
for (UINT i = 0; i < NumBuffers; i++) {
|
|
struct pipe_constant_buffer cb;
|
|
memset(&cb, 0, sizeof cb);
|
|
cb.buffer = CastPipeResource(phBuffers[i]);
|
|
cb.buffer_offset = 0;
|
|
cb.buffer_size = cb.buffer ? cb.buffer->width0 : 0;
|
|
pipe->set_constant_buffer(pipe,
|
|
shader_type,
|
|
StartBuffer + i,
|
|
FALSE,
|
|
&cb);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* SetSamplers --
|
|
*
|
|
* Update the driver's currently bound sampler state.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
static void
|
|
SetSamplers(enum pipe_shader_type shader_type, // IN
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT Offset, // IN
|
|
UINT NumSamplers, // IN
|
|
const D3D10DDI_HSAMPLER *phSamplers) // IN
|
|
{
|
|
Device *pDevice = CastDevice(hDevice);
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
|
|
void **samplers = pDevice->samplers[shader_type];
|
|
for (UINT i = 0; i < NumSamplers; i++) {
|
|
assert(Offset + i < PIPE_MAX_SAMPLERS);
|
|
samplers[Offset + i] = CastPipeSamplerState(phSamplers[i]);
|
|
}
|
|
|
|
pipe->bind_sampler_states(pipe, shader_type, 0, PIPE_MAX_SAMPLERS, samplers);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* SetSamplers --
|
|
*
|
|
* Update the driver's currently bound sampler state.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
static void
|
|
SetShaderResources(enum pipe_shader_type shader_type, // IN
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT Offset, // IN
|
|
UINT NumViews, // IN
|
|
const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
|
|
{
|
|
Device *pDevice = CastDevice(hDevice);
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
|
|
assert(Offset + NumViews <= D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
|
|
|
|
struct pipe_sampler_view **sampler_views = pDevice->sampler_views[shader_type];
|
|
for (UINT i = 0; i < NumViews; i++) {
|
|
struct pipe_sampler_view *sampler_view =
|
|
CastPipeShaderResourceView(phShaderResourceViews[i]);
|
|
if (Offset + i < PIPE_MAX_SHADER_SAMPLER_VIEWS) {
|
|
sampler_views[Offset + i] = sampler_view;
|
|
} else {
|
|
if (sampler_view) {
|
|
LOG_UNSUPPORTED(TRUE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* XXX: Now that the semantics are actually the same in gallium, should
|
|
* probably think about not updating all always... It should just work.
|
|
*/
|
|
pipe->set_sampler_views(pipe, shader_type, 0, PIPE_MAX_SHADER_SAMPLER_VIEWS,
|
|
0, sampler_views);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CalcPrivateShaderSize --
|
|
*
|
|
* The CalcPrivateShaderSize function determines the size of
|
|
* the user-mode display driver's private region of memory
|
|
* (that is, the size of internal driver structures, not the
|
|
* size of the resource video memory) for a shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
SIZE_T APIENTRY
|
|
CalcPrivateShaderSize(D3D10DDI_HDEVICE hDevice, // IN
|
|
__in_ecount (pShaderCode[1]) const UINT *pShaderCode, // IN
|
|
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
|
|
{
|
|
return sizeof(Shader);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* DestroyShader --
|
|
*
|
|
* The DestroyShader function destroys the specified shader object.
|
|
* The shader object can be destoyed only if it is not currently
|
|
* bound to a display device.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
DestroyShader(D3D10DDI_HDEVICE hDevice, // IN
|
|
D3D10DDI_HSHADER hShader) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
Shader *pShader = CastShader(hShader);
|
|
|
|
if (pShader->handle) {
|
|
switch (pShader->type) {
|
|
case PIPE_SHADER_FRAGMENT:
|
|
pipe->delete_fs_state(pipe, pShader->handle);
|
|
break;
|
|
case PIPE_SHADER_VERTEX:
|
|
pipe->delete_vs_state(pipe, pShader->handle);
|
|
break;
|
|
case PIPE_SHADER_GEOMETRY:
|
|
pipe->delete_gs_state(pipe, pShader->handle);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
if (pShader->state.tokens) {
|
|
ureg_free_tokens(pShader->state.tokens);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CalcPrivateSamplerSize --
|
|
*
|
|
* The CalcPrivateSamplerSize function determines the size of the
|
|
* user-mode display driver's private region of memory (that is,
|
|
* the size of internal driver structures, not the size of the
|
|
* resource video memory) for a sampler.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
SIZE_T APIENTRY
|
|
CalcPrivateSamplerSize(D3D10DDI_HDEVICE hDevice, // IN
|
|
__in const D3D10_DDI_SAMPLER_DESC *pSamplerDesc) // IN
|
|
{
|
|
return sizeof(SamplerState);
|
|
}
|
|
|
|
|
|
static uint
|
|
translate_address_mode(D3D10_DDI_TEXTURE_ADDRESS_MODE AddressMode)
|
|
{
|
|
switch (AddressMode) {
|
|
case D3D10_DDI_TEXTURE_ADDRESS_WRAP:
|
|
return PIPE_TEX_WRAP_REPEAT;
|
|
case D3D10_DDI_TEXTURE_ADDRESS_MIRROR:
|
|
return PIPE_TEX_WRAP_MIRROR_REPEAT;
|
|
case D3D10_DDI_TEXTURE_ADDRESS_CLAMP:
|
|
return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
|
case D3D10_DDI_TEXTURE_ADDRESS_BORDER:
|
|
return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
|
|
case D3D10_DDI_TEXTURE_ADDRESS_MIRRORONCE:
|
|
return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
|
|
default:
|
|
assert(0);
|
|
return PIPE_TEX_WRAP_REPEAT;
|
|
}
|
|
}
|
|
|
|
static uint
|
|
translate_comparison(D3D10_DDI_COMPARISON_FUNC Func)
|
|
{
|
|
switch (Func) {
|
|
case D3D10_DDI_COMPARISON_NEVER:
|
|
return PIPE_FUNC_NEVER;
|
|
case D3D10_DDI_COMPARISON_LESS:
|
|
return PIPE_FUNC_LESS;
|
|
case D3D10_DDI_COMPARISON_EQUAL:
|
|
return PIPE_FUNC_EQUAL;
|
|
case D3D10_DDI_COMPARISON_LESS_EQUAL:
|
|
return PIPE_FUNC_LEQUAL;
|
|
case D3D10_DDI_COMPARISON_GREATER:
|
|
return PIPE_FUNC_GREATER;
|
|
case D3D10_DDI_COMPARISON_NOT_EQUAL:
|
|
return PIPE_FUNC_NOTEQUAL;
|
|
case D3D10_DDI_COMPARISON_GREATER_EQUAL:
|
|
return PIPE_FUNC_GEQUAL;
|
|
case D3D10_DDI_COMPARISON_ALWAYS:
|
|
return PIPE_FUNC_ALWAYS;
|
|
default:
|
|
assert(0);
|
|
return PIPE_FUNC_ALWAYS;
|
|
}
|
|
}
|
|
|
|
static uint
|
|
translate_filter(D3D10_DDI_FILTER_TYPE Filter)
|
|
{
|
|
switch (Filter) {
|
|
case D3D10_DDI_FILTER_TYPE_POINT:
|
|
return PIPE_TEX_FILTER_NEAREST;
|
|
case D3D10_DDI_FILTER_TYPE_LINEAR:
|
|
return PIPE_TEX_FILTER_LINEAR;
|
|
default:
|
|
assert(0);
|
|
return PIPE_TEX_FILTER_NEAREST;
|
|
}
|
|
}
|
|
|
|
static uint
|
|
translate_min_filter(D3D10_DDI_FILTER Filter)
|
|
{
|
|
return translate_filter(D3D10_DDI_DECODE_MIN_FILTER(Filter));
|
|
}
|
|
|
|
static uint
|
|
translate_mag_filter(D3D10_DDI_FILTER Filter)
|
|
{
|
|
return translate_filter(D3D10_DDI_DECODE_MAG_FILTER(Filter));
|
|
}
|
|
|
|
/* Gallium uses a different enum for mipfilters, to accomodate the GL
|
|
* MIPFILTER_NONE mode.
|
|
*/
|
|
static uint
|
|
translate_mip_filter(D3D10_DDI_FILTER Filter)
|
|
{
|
|
switch (D3D10_DDI_DECODE_MIP_FILTER(Filter)) {
|
|
case D3D10_DDI_FILTER_TYPE_POINT:
|
|
return PIPE_TEX_MIPFILTER_NEAREST;
|
|
case D3D10_DDI_FILTER_TYPE_LINEAR:
|
|
return PIPE_TEX_MIPFILTER_LINEAR;
|
|
default:
|
|
assert(0);
|
|
return PIPE_TEX_MIPFILTER_NEAREST;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreateSampler --
|
|
*
|
|
* The CreateSampler function creates a sampler.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
CreateSampler(D3D10DDI_HDEVICE hDevice, // IN
|
|
__in const D3D10_DDI_SAMPLER_DESC *pSamplerDesc, // IN
|
|
D3D10DDI_HSAMPLER hSampler, // IN
|
|
D3D10DDI_HRTSAMPLER hRTSampler) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
SamplerState *pSamplerState = CastSamplerState(hSampler);
|
|
|
|
struct pipe_sampler_state state;
|
|
|
|
memset(&state, 0, sizeof state);
|
|
|
|
/* d3d10 has seamless cube filtering always enabled */
|
|
state.seamless_cube_map = 1;
|
|
|
|
/* Wrapping modes. */
|
|
state.wrap_s = translate_address_mode(pSamplerDesc->AddressU);
|
|
state.wrap_t = translate_address_mode(pSamplerDesc->AddressV);
|
|
state.wrap_r = translate_address_mode(pSamplerDesc->AddressW);
|
|
|
|
/* Filtering */
|
|
state.min_img_filter = translate_min_filter(pSamplerDesc->Filter);
|
|
state.mag_img_filter = translate_mag_filter(pSamplerDesc->Filter);
|
|
state.min_mip_filter = translate_mip_filter(pSamplerDesc->Filter);
|
|
|
|
if (D3D10_DDI_DECODE_IS_ANISOTROPIC_FILTER(pSamplerDesc->Filter)) {
|
|
state.max_anisotropy = pSamplerDesc->MaxAnisotropy;
|
|
}
|
|
|
|
/* XXX: Handle the following bit.
|
|
*/
|
|
LOG_UNSUPPORTED(D3D10_DDI_DECODE_IS_TEXT_1BIT_FILTER(pSamplerDesc->Filter));
|
|
|
|
/* Comparison. */
|
|
if (D3D10_DDI_DECODE_IS_COMPARISON_FILTER(pSamplerDesc->Filter)) {
|
|
state.compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
|
|
state.compare_func = translate_comparison(pSamplerDesc->ComparisonFunc);
|
|
}
|
|
|
|
state.normalized_coords = 1;
|
|
|
|
/* Level of detail. */
|
|
state.lod_bias = pSamplerDesc->MipLODBias;
|
|
state.min_lod = pSamplerDesc->MinLOD;
|
|
state.max_lod = pSamplerDesc->MaxLOD;
|
|
|
|
/* Border color. */
|
|
state.border_color.f[0] = pSamplerDesc->BorderColor[0];
|
|
state.border_color.f[1] = pSamplerDesc->BorderColor[1];
|
|
state.border_color.f[2] = pSamplerDesc->BorderColor[2];
|
|
state.border_color.f[3] = pSamplerDesc->BorderColor[3];
|
|
|
|
pSamplerState->handle = pipe->create_sampler_state(pipe, &state);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* DestroySampler --
|
|
*
|
|
* The DestroySampler function destroys the specified sampler object.
|
|
* The sampler object can be destoyed only if it is not currently
|
|
* bound to a display device.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
DestroySampler(D3D10DDI_HDEVICE hDevice, // IN
|
|
D3D10DDI_HSAMPLER hSampler) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
SamplerState *pSamplerState = CastSamplerState(hSampler);
|
|
|
|
pipe->delete_sampler_state(pipe, pSamplerState->handle);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreateVertexShader --
|
|
*
|
|
* The CreateVertexShader function creates a vertex shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
CreateVertexShader(D3D10DDI_HDEVICE hDevice, // IN
|
|
__in_ecount (pShaderCode[1]) const UINT *pCode, // IN
|
|
D3D10DDI_HSHADER hShader, // IN
|
|
D3D10DDI_HRTSHADER hRTShader, // IN
|
|
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
Shader *pShader = CastShader(hShader);
|
|
|
|
pShader->type = PIPE_SHADER_VERTEX;
|
|
pShader->output_resolved = TRUE;
|
|
|
|
memset(&pShader->state, 0, sizeof pShader->state);
|
|
pShader->state.tokens = Shader_tgsi_translate(pCode, pShader->output_mapping);
|
|
|
|
pShader->handle = pipe->create_vs_state(pipe, &pShader->state);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* VsSetShader --
|
|
*
|
|
* The VsSetShader function sets the vertex shader code so that all
|
|
* of the subsequent drawing operations use that code.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
VsSetShader(D3D10DDI_HDEVICE hDevice, // IN
|
|
D3D10DDI_HSHADER hShader) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
Device *pDevice = CastDevice(hDevice);
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
Shader *pShader = CastShader(hShader);
|
|
void *state = CastPipeShader(hShader);
|
|
|
|
pDevice->bound_vs = pShader;
|
|
if (!state) {
|
|
state = pDevice->empty_vs;
|
|
}
|
|
|
|
pipe->bind_vs_state(pipe, state);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* VsSetShaderResources --
|
|
*
|
|
* The VsSetShaderResources function sets resources for a
|
|
* vertex shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
VsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT Offset, // IN
|
|
UINT NumViews, // IN
|
|
__in_ecount (NumViews)
|
|
const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetShaderResources(PIPE_SHADER_VERTEX, hDevice, Offset, NumViews, phShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* VsSetConstantBuffers --
|
|
*
|
|
* The VsSetConstantBuffers function sets constant buffers
|
|
* for a vertex shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
VsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT StartBuffer, // IN
|
|
UINT NumBuffers, // IN
|
|
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetConstantBuffers(PIPE_SHADER_VERTEX,
|
|
hDevice, StartBuffer, NumBuffers, phBuffers);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* VsSetSamplers --
|
|
*
|
|
* The VsSetSamplers function sets samplers for a vertex shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
VsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT Offset, // IN
|
|
UINT NumSamplers, // IN
|
|
__in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetSamplers(PIPE_SHADER_VERTEX, hDevice, Offset, NumSamplers, phSamplers);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreateGeometryShader --
|
|
*
|
|
* The CreateGeometryShader function creates a geometry shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
CreateGeometryShader(D3D10DDI_HDEVICE hDevice, // IN
|
|
__in_ecount (pShaderCode[1]) const UINT *pShaderCode, // IN
|
|
D3D10DDI_HSHADER hShader, // IN
|
|
D3D10DDI_HRTSHADER hRTShader, // IN
|
|
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
Shader *pShader = CastShader(hShader);
|
|
|
|
pShader->type = PIPE_SHADER_GEOMETRY;
|
|
pShader->output_resolved = TRUE;
|
|
|
|
memset(&pShader->state, 0, sizeof pShader->state);
|
|
pShader->state.tokens = Shader_tgsi_translate(pShaderCode, pShader->output_mapping);
|
|
|
|
pShader->handle = pipe->create_gs_state(pipe, &pShader->state);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* GsSetShader --
|
|
*
|
|
* The GsSetShader function sets the geometry shader code so that
|
|
* all of the subsequent drawing operations use that code.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
GsSetShader(D3D10DDI_HDEVICE hDevice, // IN
|
|
D3D10DDI_HSHADER hShader) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
Device *pDevice = CastDevice(hDevice);
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
void *state = CastPipeShader(hShader);
|
|
Shader *pShader = CastShader(hShader);
|
|
|
|
assert(pipe->bind_gs_state);
|
|
|
|
if (pShader && !pShader->state.tokens) {
|
|
pDevice->bound_empty_gs = pShader;
|
|
} else {
|
|
pDevice->bound_empty_gs = NULL;
|
|
pipe->bind_gs_state(pipe, state);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* GsSetShaderResources --
|
|
*
|
|
* The GsSetShaderResources function sets resources for a
|
|
* geometry shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
GsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT Offset, // IN
|
|
UINT NumViews, // IN
|
|
__in_ecount (NumViews)
|
|
const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetShaderResources(PIPE_SHADER_GEOMETRY, hDevice, Offset, NumViews, phShaderResourceViews);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* GsSetConstantBuffers --
|
|
*
|
|
* The GsSetConstantBuffers function sets constant buffers for
|
|
* a geometry shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
GsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT StartBuffer, // IN
|
|
UINT NumBuffers, // IN
|
|
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetConstantBuffers(PIPE_SHADER_GEOMETRY,
|
|
hDevice, StartBuffer, NumBuffers, phBuffers);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* GsSetSamplers --
|
|
*
|
|
* The GsSetSamplers function sets samplers for a geometry shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
GsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT Offset, // IN
|
|
UINT NumSamplers, // IN
|
|
__in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetSamplers(PIPE_SHADER_GEOMETRY, hDevice, Offset, NumSamplers, phSamplers);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CalcPrivateGeometryShaderWithStreamOutput --
|
|
*
|
|
* The CalcPrivateGeometryShaderWithStreamOutput function determines
|
|
* the size of the user-mode display driver's private region of memory
|
|
* (that is, the size of internal driver structures, not the size of
|
|
* the resource video memory) for a geometry shader with stream output.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
SIZE_T APIENTRY
|
|
CalcPrivateGeometryShaderWithStreamOutput(
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
__in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT *pCreateGeometryShaderWithStreamOutput, // IN
|
|
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
return sizeof(Shader);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreateGeometryShaderWithStreamOutput --
|
|
*
|
|
* The CreateGeometryShaderWithStreamOutput function creates a
|
|
* geometry shader with stream output.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
CreateGeometryShaderWithStreamOutput(
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
__in const D3D10DDIARG_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT *pData, // IN
|
|
D3D10DDI_HSHADER hShader, // IN
|
|
D3D10DDI_HRTSHADER hRTShader, // IN
|
|
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
Shader *pShader = CastShader(hShader);
|
|
int total_components[PIPE_MAX_SO_BUFFERS] = {0};
|
|
unsigned num_holes = 0;
|
|
boolean all_slot_zero = TRUE;
|
|
|
|
pShader->type = PIPE_SHADER_GEOMETRY;
|
|
|
|
memset(&pShader->state, 0, sizeof pShader->state);
|
|
if (pData->pShaderCode) {
|
|
pShader->state.tokens = Shader_tgsi_translate(pData->pShaderCode,
|
|
pShader->output_mapping);
|
|
}
|
|
pShader->output_resolved = (pShader->state.tokens != NULL);
|
|
|
|
for (unsigned i = 0; i < pData->NumEntries; ++i) {
|
|
CONST D3D10DDIARG_STREAM_OUTPUT_DECLARATION_ENTRY* pOutputStreamDecl =
|
|
&pData->pOutputStreamDecl[i];
|
|
BYTE RegisterMask = pOutputStreamDecl->RegisterMask;
|
|
unsigned start_component = 0;
|
|
unsigned num_components = 0;
|
|
if (RegisterMask) {
|
|
while ((RegisterMask & 1) == 0) {
|
|
++start_component;
|
|
RegisterMask >>= 1;
|
|
}
|
|
while (RegisterMask) {
|
|
++num_components;
|
|
RegisterMask >>= 1;
|
|
}
|
|
assert(start_component < 4);
|
|
assert(1 <= num_components && num_components <= 4);
|
|
LOG_UNSUPPORTED(((1 << num_components) - 1) << start_component !=
|
|
pOutputStreamDecl->RegisterMask);
|
|
}
|
|
|
|
if (pOutputStreamDecl->RegisterIndex == 0xffffffff) {
|
|
++num_holes;
|
|
} else {
|
|
unsigned idx = i - num_holes;
|
|
pShader->state.stream_output.output[idx].start_component =
|
|
start_component;
|
|
pShader->state.stream_output.output[idx].num_components =
|
|
num_components;
|
|
pShader->state.stream_output.output[idx].output_buffer =
|
|
pOutputStreamDecl->OutputSlot;
|
|
pShader->state.stream_output.output[idx].register_index =
|
|
ShaderFindOutputMapping(pShader, pOutputStreamDecl->RegisterIndex);
|
|
pShader->state.stream_output.output[idx].dst_offset =
|
|
total_components[pOutputStreamDecl->OutputSlot];
|
|
if (pOutputStreamDecl->OutputSlot != 0)
|
|
all_slot_zero = FALSE;
|
|
}
|
|
total_components[pOutputStreamDecl->OutputSlot] += num_components;
|
|
}
|
|
pShader->state.stream_output.num_outputs = pData->NumEntries - num_holes;
|
|
for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; ++i) {
|
|
/* stream_output.stride[i] is in dwords */
|
|
if (all_slot_zero) {
|
|
pShader->state.stream_output.stride[i] =
|
|
pData->StreamOutputStrideInBytes / sizeof(float);
|
|
} else {
|
|
pShader->state.stream_output.stride[i] = total_components[i];
|
|
}
|
|
}
|
|
|
|
pShader->handle = pipe->create_gs_state(pipe, &pShader->state);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* SoSetTargets --
|
|
*
|
|
* The SoSetTargets function sets stream output target resources.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
SoSetTargets(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT SOTargets, // IN
|
|
UINT ClearTargets, // IN
|
|
__in_ecount (SOTargets) const D3D10DDI_HRESOURCE *phResource, // IN
|
|
__in_ecount (SOTargets) const UINT *pOffsets) // IN
|
|
{
|
|
unsigned i;
|
|
|
|
LOG_ENTRYPOINT();
|
|
|
|
Device *pDevice = CastDevice(hDevice);
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
|
|
assert(SOTargets + ClearTargets <= PIPE_MAX_SO_BUFFERS);
|
|
|
|
for (i = 0; i < SOTargets; ++i) {
|
|
Resource *resource = CastResource(phResource[i]);
|
|
struct pipe_resource *buffer = CastPipeResource(phResource[i]);
|
|
struct pipe_stream_output_target *so_target =
|
|
resource ? resource->so_target : NULL;
|
|
|
|
if (buffer) {
|
|
unsigned buffer_size = buffer->width0;
|
|
|
|
if (!so_target ||
|
|
so_target->buffer != buffer ||
|
|
so_target->buffer_size != buffer_size) {
|
|
if (so_target) {
|
|
pipe_so_target_reference(&so_target, NULL);
|
|
}
|
|
so_target = pipe->create_stream_output_target(pipe, buffer,
|
|
0,/*buffer offset*/
|
|
buffer_size);
|
|
resource->so_target = so_target;
|
|
}
|
|
}
|
|
pDevice->so_targets[i] = so_target;
|
|
}
|
|
|
|
for (i = 0; i < ClearTargets; ++i) {
|
|
pDevice->so_targets[SOTargets + i] = NULL;
|
|
}
|
|
|
|
if (!pipe->set_stream_output_targets) {
|
|
LOG_UNSUPPORTED(pipe->set_stream_output_targets);
|
|
return;
|
|
}
|
|
|
|
pipe->set_stream_output_targets(pipe, SOTargets, pDevice->so_targets,
|
|
pOffsets);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreatePixelShader --
|
|
*
|
|
* The CreatePixelShader function converts pixel shader code into a
|
|
* hardware-specific format and associates this code with a
|
|
* shader handle.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
CreatePixelShader(D3D10DDI_HDEVICE hDevice, // IN
|
|
__in_ecount (pShaderCode[1]) const UINT *pShaderCode, // IN
|
|
D3D10DDI_HSHADER hShader, // IN
|
|
D3D10DDI_HRTSHADER hRTShader, // IN
|
|
__in const D3D10DDIARG_STAGE_IO_SIGNATURES *pSignatures) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
Shader *pShader = CastShader(hShader);
|
|
|
|
pShader->type = PIPE_SHADER_FRAGMENT;
|
|
pShader->output_resolved = TRUE;
|
|
|
|
memset(&pShader->state, 0, sizeof pShader->state);
|
|
pShader->state.tokens = Shader_tgsi_translate(pShaderCode,
|
|
pShader->output_mapping);
|
|
|
|
pShader->handle = pipe->create_fs_state(pipe, &pShader->state);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* PsSetShader --
|
|
*
|
|
* The PsSetShader function sets a pixel shader to be used
|
|
* in all drawing operations.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
PsSetShader(D3D10DDI_HDEVICE hDevice, // IN
|
|
D3D10DDI_HSHADER hShader) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
Device *pDevice = CastDevice(hDevice);
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
void *state = CastPipeShader(hShader);
|
|
|
|
if (!state) {
|
|
state = pDevice->empty_fs;
|
|
}
|
|
|
|
pipe->bind_fs_state(pipe, state);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* PsSetShaderResources --
|
|
*
|
|
* The PsSetShaderResources function sets resources for a pixel shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
PsSetShaderResources(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT Offset, // IN
|
|
UINT NumViews, // IN
|
|
__in_ecount (NumViews)
|
|
const D3D10DDI_HSHADERRESOURCEVIEW *phShaderResourceViews) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetShaderResources(PIPE_SHADER_FRAGMENT, hDevice, Offset, NumViews, phShaderResourceViews);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* PsSetConstantBuffers --
|
|
*
|
|
* The PsSetConstantBuffers function sets constant buffers for
|
|
* a pixel shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
PsSetConstantBuffers(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT StartBuffer, // IN
|
|
UINT NumBuffers, // IN
|
|
__in_ecount (NumBuffers) const D3D10DDI_HRESOURCE *phBuffers) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetConstantBuffers(PIPE_SHADER_FRAGMENT,
|
|
hDevice, StartBuffer, NumBuffers, phBuffers);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* PsSetSamplers --
|
|
*
|
|
* The PsSetSamplers function sets samplers for a pixel shader.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
PsSetSamplers(D3D10DDI_HDEVICE hDevice, // IN
|
|
UINT Offset, // IN
|
|
UINT NumSamplers, // IN
|
|
__in_ecount (NumSamplers) const D3D10DDI_HSAMPLER *phSamplers) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
SetSamplers(PIPE_SHADER_FRAGMENT, hDevice, Offset, NumSamplers, phSamplers);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* ShaderResourceViewReadAfterWriteHazard --
|
|
*
|
|
* The ShaderResourceViewReadAfterWriteHazard function informs
|
|
* the usermode display driver that the specified resource was
|
|
* used as an output from the graphics processing unit (GPU)
|
|
* and that the resource will be used as an input to the GPU.
|
|
* A shader resource view is also provided to indicate which
|
|
* view caused the hazard.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
ShaderResourceViewReadAfterWriteHazard(D3D10DDI_HDEVICE hDevice, // IN
|
|
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
|
|
D3D10DDI_HRESOURCE hResource) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
/* Not actually necessary */
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CalcPrivateShaderResourceViewSize --
|
|
*
|
|
* The CalcPrivateShaderResourceViewSize function determines the size
|
|
* of the usermode display driver's private region of memory
|
|
* (that is, the size of internal driver structures, not the size of
|
|
* the resource video memory) for a shader resource view.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
SIZE_T APIENTRY
|
|
CalcPrivateShaderResourceViewSize(
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
__in const D3D10DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView) // IN
|
|
{
|
|
return sizeof(ShaderResourceView);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CalcPrivateShaderResourceViewSize --
|
|
*
|
|
* The CalcPrivateShaderResourceViewSize function determines the size
|
|
* of the usermode display driver's private region of memory
|
|
* (that is, the size of internal driver structures, not the size of
|
|
* the resource video memory) for a shader resource view.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
SIZE_T APIENTRY
|
|
CalcPrivateShaderResourceViewSize1(
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
__in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView) // IN
|
|
{
|
|
return sizeof(ShaderResourceView);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreateShaderResourceView --
|
|
*
|
|
* The CreateShaderResourceView function creates a shader
|
|
* resource view.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
CreateShaderResourceView(
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
__in const D3D10DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView, // IN
|
|
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
|
|
D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
|
|
struct pipe_resource *resource;
|
|
enum pipe_format format;
|
|
|
|
struct pipe_sampler_view desc;
|
|
memset(&desc, 0, sizeof desc);
|
|
resource = CastPipeResource(pCreateSRView->hDrvResource);
|
|
format = FormatTranslate(pCreateSRView->Format, FALSE);
|
|
|
|
u_sampler_view_default_template(&desc,
|
|
resource,
|
|
format);
|
|
|
|
switch (pCreateSRView->ResourceDimension) {
|
|
case D3D10DDIRESOURCE_BUFFER: {
|
|
const struct util_format_description *fdesc = util_format_description(format);
|
|
desc.u.buf.offset = pCreateSRView->Buffer.FirstElement *
|
|
(fdesc->block.bits / 8) * fdesc->block.width;
|
|
desc.u.buf.size = pCreateSRView->Buffer.NumElements *
|
|
(fdesc->block.bits / 8) * fdesc->block.width;
|
|
}
|
|
break;
|
|
case D3D10DDIRESOURCE_TEXTURE1D:
|
|
desc.u.tex.first_level = pCreateSRView->Tex1D.MostDetailedMip;
|
|
desc.u.tex.last_level = pCreateSRView->Tex1D.MipLevels - 1 + desc.u.tex.first_level;
|
|
desc.u.tex.first_layer = pCreateSRView->Tex1D.FirstArraySlice;
|
|
desc.u.tex.last_layer = pCreateSRView->Tex1D.ArraySize - 1 + desc.u.tex.first_layer;
|
|
assert(pCreateSRView->Tex1D.MipLevels != 0 && pCreateSRView->Tex1D.MipLevels != (UINT)-1);
|
|
assert(pCreateSRView->Tex1D.ArraySize != 0 && pCreateSRView->Tex1D.ArraySize != (UINT)-1);
|
|
break;
|
|
case D3D10DDIRESOURCE_TEXTURE2D:
|
|
desc.u.tex.first_level = pCreateSRView->Tex2D.MostDetailedMip;
|
|
desc.u.tex.last_level = pCreateSRView->Tex2D.MipLevels - 1 + desc.u.tex.first_level;
|
|
desc.u.tex.first_layer = pCreateSRView->Tex2D.FirstArraySlice;
|
|
desc.u.tex.last_layer = pCreateSRView->Tex2D.ArraySize - 1 + desc.u.tex.first_layer;
|
|
assert(pCreateSRView->Tex2D.MipLevels != 0 && pCreateSRView->Tex2D.MipLevels != (UINT)-1);
|
|
assert(pCreateSRView->Tex2D.ArraySize != 0 && pCreateSRView->Tex2D.ArraySize != (UINT)-1);
|
|
break;
|
|
case D3D10DDIRESOURCE_TEXTURE3D:
|
|
desc.u.tex.first_level = pCreateSRView->Tex3D.MostDetailedMip;
|
|
desc.u.tex.last_level = pCreateSRView->Tex3D.MipLevels - 1 + desc.u.tex.first_level;
|
|
/* layer info filled in by default_template */
|
|
assert(pCreateSRView->Tex3D.MipLevels != 0 && pCreateSRView->Tex3D.MipLevels != (UINT)-1);
|
|
break;
|
|
case D3D10DDIRESOURCE_TEXTURECUBE:
|
|
desc.u.tex.first_level = pCreateSRView->TexCube.MostDetailedMip;
|
|
desc.u.tex.last_level = pCreateSRView->TexCube.MipLevels - 1 + desc.u.tex.first_level;
|
|
/* layer info filled in by default_template */
|
|
assert(pCreateSRView->TexCube.MipLevels != 0 && pCreateSRView->TexCube.MipLevels != (UINT)-1);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
return;
|
|
}
|
|
|
|
pSRView->handle = pipe->create_sampler_view(pipe, resource, &desc);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* CreateShaderResourceView1 --
|
|
*
|
|
* The CreateShaderResourceView function creates a shader
|
|
* resource view.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
CreateShaderResourceView1(
|
|
D3D10DDI_HDEVICE hDevice, // IN
|
|
__in const D3D10_1DDIARG_CREATESHADERRESOURCEVIEW *pCreateSRView, // IN
|
|
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView, // IN
|
|
D3D10DDI_HRTSHADERRESOURCEVIEW hRTShaderResourceView) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
struct pipe_context *pipe = CastPipeContext(hDevice);
|
|
ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
|
|
struct pipe_resource *resource;
|
|
enum pipe_format format;
|
|
|
|
struct pipe_sampler_view desc;
|
|
memset(&desc, 0, sizeof desc);
|
|
resource = CastPipeResource(pCreateSRView->hDrvResource);
|
|
format = FormatTranslate(pCreateSRView->Format, FALSE);
|
|
|
|
u_sampler_view_default_template(&desc,
|
|
resource,
|
|
format);
|
|
|
|
switch (pCreateSRView->ResourceDimension) {
|
|
case D3D10DDIRESOURCE_BUFFER: {
|
|
const struct util_format_description *fdesc = util_format_description(format);
|
|
desc.u.buf.offset = pCreateSRView->Buffer.FirstElement *
|
|
(fdesc->block.bits / 8) * fdesc->block.width;
|
|
desc.u.buf.size = pCreateSRView->Buffer.NumElements *
|
|
(fdesc->block.bits / 8) * fdesc->block.width;
|
|
}
|
|
break;
|
|
case D3D10DDIRESOURCE_TEXTURE1D:
|
|
desc.u.tex.first_level = pCreateSRView->Tex1D.MostDetailedMip;
|
|
desc.u.tex.last_level = pCreateSRView->Tex1D.MipLevels - 1 + desc.u.tex.first_level;
|
|
desc.u.tex.first_layer = pCreateSRView->Tex1D.FirstArraySlice;
|
|
desc.u.tex.last_layer = pCreateSRView->Tex1D.ArraySize - 1 + desc.u.tex.first_layer;
|
|
assert(pCreateSRView->Tex1D.MipLevels != 0 && pCreateSRView->Tex1D.MipLevels != (UINT)-1);
|
|
assert(pCreateSRView->Tex1D.ArraySize != 0 && pCreateSRView->Tex1D.ArraySize != (UINT)-1);
|
|
break;
|
|
case D3D10DDIRESOURCE_TEXTURE2D:
|
|
desc.u.tex.first_level = pCreateSRView->Tex2D.MostDetailedMip;
|
|
desc.u.tex.last_level = pCreateSRView->Tex2D.MipLevels - 1 + desc.u.tex.first_level;
|
|
desc.u.tex.first_layer = pCreateSRView->Tex2D.FirstArraySlice;
|
|
desc.u.tex.last_layer = pCreateSRView->Tex2D.ArraySize - 1 + desc.u.tex.first_layer;
|
|
assert(pCreateSRView->Tex2D.MipLevels != 0 && pCreateSRView->Tex2D.MipLevels != (UINT)-1);
|
|
assert(pCreateSRView->Tex2D.ArraySize != 0 && pCreateSRView->Tex2D.ArraySize != (UINT)-1);
|
|
break;
|
|
case D3D10DDIRESOURCE_TEXTURE3D:
|
|
desc.u.tex.first_level = pCreateSRView->Tex3D.MostDetailedMip;
|
|
desc.u.tex.last_level = pCreateSRView->Tex3D.MipLevels - 1 + desc.u.tex.first_level;
|
|
/* layer info filled in by default_template */
|
|
assert(pCreateSRView->Tex3D.MipLevels != 0 && pCreateSRView->Tex3D.MipLevels != (UINT)-1);
|
|
break;
|
|
case D3D10DDIRESOURCE_TEXTURECUBE:
|
|
desc.u.tex.first_level = pCreateSRView->TexCube.MostDetailedMip;
|
|
desc.u.tex.last_level = pCreateSRView->TexCube.MipLevels - 1 + desc.u.tex.first_level;
|
|
desc.u.tex.first_layer = pCreateSRView->TexCube.First2DArrayFace;
|
|
desc.u.tex.last_layer = 6*pCreateSRView->TexCube.NumCubes - 1 +
|
|
pCreateSRView->TexCube.First2DArrayFace;
|
|
assert(pCreateSRView->TexCube.MipLevels != 0 && pCreateSRView->TexCube.MipLevels != (UINT)-1);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
return;
|
|
}
|
|
|
|
pSRView->handle = pipe->create_sampler_view(pipe, resource, &desc);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* DestroyShaderResourceView --
|
|
*
|
|
* The DestroyShaderResourceView function destroys the specified
|
|
* shader resource view object. The shader resource view object
|
|
* can be destoyed only if it is not currently bound to a
|
|
* display device.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
DestroyShaderResourceView(D3D10DDI_HDEVICE hDevice, // IN
|
|
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
ShaderResourceView *pSRView = CastShaderResourceView(hShaderResourceView);
|
|
|
|
pipe_sampler_view_reference(&pSRView->handle, NULL);
|
|
}
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------
|
|
*
|
|
* GenMips --
|
|
*
|
|
* The GenMips function generates the lower MIP-map levels
|
|
* on the specified shader-resource view.
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
void APIENTRY
|
|
GenMips(D3D10DDI_HDEVICE hDevice, // IN
|
|
D3D10DDI_HSHADERRESOURCEVIEW hShaderResourceView) // IN
|
|
{
|
|
LOG_ENTRYPOINT();
|
|
|
|
Device *pDevice = CastDevice(hDevice);
|
|
if (!CheckPredicate(pDevice)) {
|
|
return;
|
|
}
|
|
|
|
struct pipe_context *pipe = pDevice->pipe;
|
|
struct pipe_sampler_view *sampler_view = CastPipeShaderResourceView(hShaderResourceView);
|
|
|
|
util_gen_mipmap(pipe,
|
|
sampler_view->texture,
|
|
sampler_view->format,
|
|
sampler_view->u.tex.first_level,
|
|
sampler_view->u.tex.last_level,
|
|
sampler_view->u.tex.first_layer,
|
|
sampler_view->u.tex.last_layer,
|
|
PIPE_TEX_FILTER_LINEAR);
|
|
}
|
|
|
|
|
|
unsigned
|
|
ShaderFindOutputMapping(Shader *shader, unsigned registerIndex)
|
|
{
|
|
if (!shader || !shader->state.tokens)
|
|
return registerIndex;
|
|
|
|
for (unsigned i = 0; i < PIPE_MAX_SHADER_OUTPUTS; ++i) {
|
|
if (shader->output_mapping[i] == registerIndex)
|
|
return i;
|
|
}
|
|
return registerIndex;
|
|
}
|